lundi 23 mai 2016

Which is the best way to add a retry/rollback mechanism for sync/async tasks to existing legacy code in C#?

Imagine off a WebForms application where there is a main method named CreateAll(). I can describe the process of the method tasks step by step as follows:

1) Stores to database (Update/Create Db items 3-4 times)

2) Starts a new thread

3) Result1 = Calls a soap service, and by using a timeout threshold it checks the status and after x minutes.The it continues (status now is OK and it isn't means failure)

4) Stores to database (Update/Create Db items 3-4 times)

5) result2 = Calls a soap service (In a fire and forget way)

6) Updates a configuration file (that is taken actually from result1)

7) By using callback requests it checks every x secs at front part the state of the result2 and the UI shows a progress bar.If the process is finished (100%) it means success

I am considering that all of them are tasks that can be grouped by their type.Basically the several types of actions are :

  • Type1: DB transaction
  • Type2: Service communication/transaction
  • Type3: Config file I/O transactions

I want to add a rollback/retry mechanism to the existing implementation and to use a task oriented architecture and refactor existing legacy code.

I found that something like Memento Design Pattern OR Command Pattern in C# could help for this purpose.I also found the msdn Retry Pattern description interesting. I don't realy know and I want someone to lead me to the safest and best decision...

Can you suggest me the best way for this case to keep the existing implementation and the flow but wrapping it in a general and abstract retry/rollback/tasklist implementation ?

The final implementation must be able to retry in every case (whatever task or general failure such as timeout etc throughout the general createAll process) and also there would be a rollback decision list where the app must be able to rollback all the tasks that was accomplished.


PseudoCode that might be helpful:

class something
{  
    static result CreateAll(object1 obj1, object2 obj2 ...)
    {
        //Save to database obj1
        //...
        //Update to database obj1 
        //
        //NEW THREAD
       //Start a new thread with obj1, obj2 ...CreateAll
       //...          
     } 

    void CreateAllAsync()
    {
        //Type1 Save to database obj1
        //...
        //Type1 Update to database obj2

        //Type2 Call Web Service to create obj1 on the service (not async)

        while (state != null && now < times)
        {
            if (status == "OK")
            break;      
            else
            //Wait for X seconds
        }

        //Check status continue or general failure
        //Type1 Update to database obj2 and obj1

        //Type2 Call Web Service to create obj2 on the service (fire and forget)

        //Type3 Update Configuration File
        //Type1 Update to database obj2 and obj1
        //..   

    return;
}

//Then the UI takes the responsibility to check the status of result2

Aucun commentaire:

Enregistrer un commentaire