tags:

views:

72

answers:

1

Hello,

We have a windows service in C++/ MFC which has to carry out a number of tasks on the host workstation some of which may be long running and may fail a few times before they are completed. Each task will only need to be completed once and sequentially.

I was of thinking of some form of callback initially to retry the failed task but each function has totally different parameters and the code has already been written and tested and just needs a re-queuing method.

I thought we could write the failed task to the registry, sleep() for a while and then restart the service. Is there a better approach?

TIA..

+2  A: 

I'm doing quite the same thing in my professional project. My server component is getting runnable objects from different sources and execute them sequentially in a separated thread. All my runnable objects are using different parameters but they all have one function run(void* pUserParam). the void* parameters is a special object that contains a collection of field with different type (double, string, etc...).

My component is queuing the runnable object and launch a new one each time the thread is freed. Of course my component is sleeping when queue is empty and wake up when an object arrives. In your case when a task fail you just need to re-queue it and it will automatically retry the task later.

To achieve these you need:

  1. a Pool mechanism that manage a queue of tasks,
  2. a task object that contains all information about the runnable object to launch and the parameters,
  3. a runnable object that contains your action to execute.

How it works:

Your service is listening for demands,

  1. When a demand arrives, it give it to the Pool mechanism,
  2. The Pool take the runnable object and its parameter(s) and create a task. This task is queued, (2b. If the queue was empty, the pool wakes up the execution thread,)
  3. The Thread pick up one task from the queue and execute it calling the Run() function of the runnable object and passing to it the parameters previously stored in the task, (3b. If the task failed, the thread re-queue a task with the runnable object and its parameter(s),)
  4. The thread picks up a new task or sleeps if queue is empty.

This is my approach and I know this works fine. I know with this method you need to rewrite a part of your application but then the only thing to modify when adding a sort of task is to create a new runnable object (one sort of task => one runnable object that inherit from the abstract one).

Hope this will help you

Patrice Bernassola