SuperJMN (1) [Avatar] Offline
#1
Hello!

I'm interested in solving this problem using Rx/ RxUI.

Basically, it models a process that happens on a conveyor belt.

The belt has boxes on it, ordered with numbers a a natural sequence (box 1, box 2...)

This is the process:

1. A picture of the box is taken and sent to a folder
2. The picture is OCRed (optical recognition)
3. The results of the OCR are sent to a DB using an external "web service"

An important thing to notice is that every box is processed before the next, so box 1 will always come before 2, and 2 before 3. The system doesn't support changing the order of the boxes like 1, 5, 2, 3, 4

The problem comes when an error happens in the middle of the process.

Between step 1 and 2, the camera can fail to take the picture
Between step 3 and 4, the data after the OCR could be wrong
After step 4, the web service could reject our results.

Everytime an error happens, the belt stops and the user has to interact with the data in the pipeline to resume.

I would model it using something like

picture => OCR results => upload

But how to handle the interaction when an error happens?



Tamir Dresher (35) [Avatar] Offline
#2
If i understand correctly, i think this is what your'e looking for.
public static class MyObservableExtensions
{
    public static IObservable<T> CatchAndRetry<T, TException>(this IObservable<T> source, Action<TException> catchAction) 
        where TException : Exception
    {
        return source
            .Catch((TException e) =>
            {
                catchAction(e);
                return source;
            })
            .Retry();
    }
}
class Program
{
    static void Main(string[] args)
    {
        var pictureTaken = Observable.Interval(TimeSpan.FromSeconds(1)).Publish();
        var faultyPictureTaken = pictureTaken
            .Select(x =>
            {
                if (x % 6 == 0) throw new Exception("sss");
                return x;
            });

        var ocr = faultyPictureTaken
            .CatchAndRetry((Exception e) => { Console.WriteLine("waiting for user to fix error in picture"); })
            .Select(x => x * 2)
            .Select(x =>
            {
                if (x % 6 == 0) throw new Exception("sss");
                return x;
            });

        ocr.CatchAndRetry((Exception e) => { Console.WriteLine("waiting for user to fix error in Ocr"); })
            .Subscribe(x => Console.WriteLine(x));

        pictureTaken.Connect();


        Console.ReadLine();
    }
}