Problem with missing events

Hi,
I had problem with asynchronous - exactly with “await”.
I described my case below.
I suppose it is something wrong in framework, but I hope I’m wrong.

Case:

Run 1000 commands which will read prices from external system. Reading is carried out using WCF.

The framework should trigger the same number of events as commands. It should be 1000 events.

But when we use await, to wait for results from WCF, the events is not invoked 1000 times. Sometimes it is about 800, another time 600, and if we have a lucky it will be 1000. It works randomly.

Solution:
I found one solution, I hope it will be fixed in framework.
I had to replace await for .Result.

Sample for await:

Task nameTask = Task.Factory.StartNew(() => {

     return string.Format("Name matching id {0} = Developer", id); 

});

return await nameTask;

Sample for .Result:
Task nameTask = Task.Factory.StartNew(() => {

             return string.Format("Name matching id {0} = Developer", id); 

});

return nameTask.Result

Best regards Daniel.

1 Like

Hi Daniel. Good to see you post! :slight_smile:

We don’t support async Event Processors. If you create an event processor with a return type other than void, you should get a compiler warning. If you are doing async void… well, you shouldn’t! :slight_smile:

See https://msdn.microsoft.com/en-us/magazine/jj991977.aspx for why not.

You should think of EventProcessors as like MVC Controller methods. You shouldn’t do too much in them. If there is something more involved than just projecting the state of an aggregate to a persisted read model, then you should ask a service (of your own code) to do it. Then you have full control and can partition and process incoming events as you need.

I’m unclear as to what you are actually doing. Are you reading from your external service within your command handler? If so, is it the command handler that is failing and rejecting the commands? This would mean that the events are not being created. How many events are created?

If, on the other hand, you are trying to issue a command from within a Policy / Reaction, then you need to handle the failure scenario.

Can you provide me with more details? Async processing of events isn’t trivial. As soon as you do things in parallel with different processing times, you need to consider things happening “out of order”.

BTW I think if you changed your lambda to be async, you could use await.

Task nameTask = Task.Factory.StartNew(async() => {

     return string.Format("Name matching id {0} = Developer", id); 

});

Hi Michael,
Thank you for your replied.
Real example was, that in job I was reading a lot of prices from WCF with several asynchronous tasks (about twelve in the same time)
I got about 90 response for one request and each response execute one command. Command should apply event. The count of command and events should be the same, but it wasn’t.
I run Task.Run and inside communication with WCF using await.
I removed Task.Run and await was replaced by .Result, and now it is slower but it works fine.

I had a problem to find what was wrong, because sometimes I had all data but on other case I hadn’t.

Hi Daniel. I can imagine it has slowed down if you’ve gone from asynchronous to synchronous! :blush:

I think this might be a conceptual/modelling problem. A command might produce an event but it can also fail. If you are going through the command pipeline and receiving a command result you won’t get an exception. Even if it is throwing an exception, that can be tricky to deal with in the async world.

More fudamental though, you shouldn’t be doing this work in an event processor. You should use your event processor to signal to something that you want the work done - a message on a queue, a rest call, etc. This other service can then notify you somehow. Maybe it produces an event when the work is complete, maybe it just calls an endpoint you have created. That’s up to you.

The event are domain events and represent state changes in the system. Even if you want the individual event, it doesn’t mean you need an individual command to produce it.

It sounds to me like you have some kind of bulk update in response to something and that this might take a long time to determine. If so, you need to model your domain for the bulk nature of the update and schedule some kind of background job to do it.

Does that make sense?

1 Like