0

I'm creating a webservice+servicebus project where user can do something like

public void ExecuteLongProcess(DateTime fromDate,string aggregateId){}

This method immediately returns but send over the bus a request for the operation.

My problems starts when multiple user ask for the long process over the same aggregateId when another one is already running.

The solution i'm thinking about is a Task that runs continuosly and look in a Queue<LongProcessTask> for a operation that must be executed so I run only one process a time or a future implementation will be multiple process if different aggregateId.

This way I don't overlap long running process over the same aggregate.

Other ideas?

Mauro Destro
  • 746
  • 12
  • 34

2 Answers2

0

I have created a TaskRunner that instantiate some continuous running Task (number depending on processor cores) that look in a concurrent queue and run each operation pending. TaskRunner get from Windsor the handler for each operation type in order to leave the processing of each operation in a class aside.

Mauro Destro
  • 746
  • 12
  • 34
0

In your answer, you say that multiple threads will take tasks from a concurrent queue. In this case there is a chance that two tasks with the same aggregateId may run at the sametime. I do not know whether this is a problem for you, if so then you must use a different queue for each aggregateId.

If the task order is not an issue then I recommend using a BlockingCollection. Because there is question : What are you planning to do with multiple consumer threads if there is no task in the concurrent queue.

while(some_condition_to_keep_thread_alive)
{
  if(!queue.TryDequeue(...))
    continue;
  else 
  {
    //do the job
  }
}

This code will make your cores go crazy if queue is empty. You need a blocking mechanism. BlockingCollection will do this for you.

Do you insist on using ConcurrentQueue? Ok SemaphoreSlim is your friend.

ali_bahoo
  • 4,732
  • 6
  • 41
  • 63
  • Yes, my queue is a ConcurrentDictionary; inside each thread I get only an operation of an aggregateId that's not running elsewhere and also ordered by queuedIn timestamp. The only thing I miss is the semaphore. I think that I can signal the threads when a new operation is queued – Mauro Destro Nov 04 '11 at 08:33
  • Beaware that ConcurrentDictionary is unordered. If order is important, you can use `ConcurrentQueue>`. Of course it is hard to say something without knowing the implemantation details of yours. – ali_bahoo Nov 04 '11 at 09:33
  • Yeah, i'm aware of this. I have a property QueuedIn in order to sort by queue insertion time – Mauro Destro Nov 04 '11 at 13:41