You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Creating AsyncSend or AsyncPublish, feels like applying concurrency at the wrong level; Send and Publish are not the 'work' boundary.
Making a Request Handler async which seems more natural as the handler is the use-case or transactional boundary and would also make sense as the Task boundary. So something like Task Handle(T command) feels like a better fit. The Command Dispatcher would then wait on the Handle method, catch any exceptions and return results. That could probably be implemented as a hander, so that you could simply declare [AsyncHandler] as an attribute over changing the signature.
The problem is that the scenario most folks are thinking about is an async ASP.NET controller action and they want to declare the method async so that it yields control on an I/O operation.
I'm still not reconciled what I want to do about this, so no decision as yet
Pondering upon this the issue that the asynchronous and synchronous pipelines are quite different. Consider that the in the Russian Doll model, if you await, then we have to consider what code will run as part of the completion (everything after the await inside the method body) and what code needs to run because we are now exiting the handler. This implies that the entire pipeline has to be async. It also means that we need to think about the default way that we call a successor now.
So I think the first thoughts here are wrong: this is a separate pipeline approach and we do need a SendAsync, PublishAsync, and PostAsync.
There is a some sharing - much of how we build a pipeline is similar, we just need different signatures, base objects in the async chain.
It would have been nice to support some async handlers in the chain, but I think the nature of async I/O and the russian doll model means that we can't effect this. So I think the whole pipeline has to be async.
The downside here, is that we won't find it easy to just call an existing pipeline using the *Async methods, you'll actually have to alter a handler to get support for async.
Ian, I have read the above and after some (but definitely still insufficient) thinking created an implementation of SendAsync. The IAmACommandProcessor interface has been extended with:
My current implementation builds a separate async pipeline, but does not break any of the existing code, tests and examples.
There is actually not much 'my' code, just (copies of) existing code with modifications.
Added:
AsyncHandlerFactory.cs
AsyncPipelines.cs
AsyncRequestHandler.cs
AsyncRequestHandlerAttribute.cs
AsyncRequestHandler.cs
IAmAnAsyncHandlerFactory.cs
IHandleRequestsAsync.cs
a working HelloWorldAsync project
Modified:
SpyCommandProcessor.cs (for tests)
CommandProcessor.cs
CommandProcessorBuilder.cs
HandlerConfiguration.cs
IAmACommandProcessor.cs
IAmALifetime.cs
Interpreter.cs
LifetimeScope.cs
PipelineBuilder.cs
SubscriberRegistry.cs
ReflectionExtensions.cs
and the solution and relevant projects
Can you please create a branch named 'async' then I will issue a PR against it and we can review and discuss the approach I have taken so far.
I have not yet created the Async equivalents of the eventsourcing, logging, monitoring and policy attributes but that is not a big deal. Also I'm still considering to support the use of 'regular' (non-async/await) handlers in the async pipeline. That shoiuld be doable. The other way around, using async handlers in a non-async pipeline, looks inadvisable.
Activity
iancooper commentedon Sep 30, 2014
Creating AsyncSend or AsyncPublish, feels like applying concurrency at the wrong level; Send and Publish are not the 'work' boundary.
Making a Request Handler async which seems more natural as the handler is the use-case or transactional boundary and would also make sense as the Task boundary. So something like Task Handle(T command) feels like a better fit. The Command Dispatcher would then wait on the Handle method, catch any exceptions and return results. That could probably be implemented as a hander, so that you could simply declare [AsyncHandler] as an attribute over changing the signature.
The problem is that the scenario most folks are thinking about is an async ASP.NET controller action and they want to declare the method async so that it yields control on an I/O operation.
I'm still not reconciled what I want to do about this, so no decision as yet
iancooper commentedon Jun 27, 2015
Pondering upon this the issue that the asynchronous and synchronous pipelines are quite different. Consider that the in the Russian Doll model, if you await, then we have to consider what code will run as part of the completion (everything after the await inside the method body) and what code needs to run because we are now exiting the handler. This implies that the entire pipeline has to be async. It also means that we need to think about the default way that we call a successor now.
So I think the first thoughts here are wrong: this is a separate pipeline approach and we do need a SendAsync, PublishAsync, and PostAsync.
There is a some sharing - much of how we build a pipeline is similar, we just need different signatures, base objects in the async chain.
It would have been nice to support some async handlers in the chain, but I think the nature of async I/O and the russian doll model means that we can't effect this. So I think the whole pipeline has to be async.
The downside here, is that we won't find it easy to just call an existing pipeline using the *Async methods, you'll actually have to alter a handler to get support for async.
Red-F commentedon Jan 1, 2016
Ian, I have read the above and after some (but definitely still insufficient) thinking created an implementation of SendAsync. The IAmACommandProcessor interface has been extended with:
My current implementation builds a separate async pipeline, but does not break any of the existing code, tests and examples.
There is actually not much 'my' code, just (copies of) existing code with modifications.
Added:
Modified:
Can you please create a branch named 'async' then I will issue a PR against it and we can review and discuss the approach I have taken so far.
I have not yet created the Async equivalents of the eventsourcing, logging, monitoring and policy attributes but that is not a big deal. Also I'm still considering to support the use of 'regular' (non-async/await) handlers in the async pipeline. That shoiuld be doable. The other way around, using async handlers in a non-async pipeline, looks inadvisable.
Regards,
Fred Hoogduin
iancooper commentedon Jan 1, 2016
I've created the async branch
56 remaining items
docs: ADR 0076 - the ordinary slice, round 7 (batch O-0076)
docs: ADR 0073 - the ordinary slice, round 7 (batch O-0073)
docs: requirements rev 25 + ADR 0074 - the ordinary slice, round 7 (b…
docs: ADRs 0070 + 0075 - the ordinary slice, round 7 (batch O-0070)
docs: ADR 0071 - the ordinary slice, round 7 (batch O-0071)
docs: requirements rev 26 + ADRs 0072/0073/0075 - FR-19/AC-20/C-14, r…
docs: requirements rev 27 + ADRs 0070/0071/0072 - AC-30's Post branch…
docs: ADR 0072 - the ordinary slice, round 7 (batch O-0072)
docs: all seven ADRs + index - the cross-ADR set-level residue, round…
fix: stop ScopedArtefactCache leaking under a racing first resolution
docs: record IAmALifetime's IAsyncDisposable break in the release notes
docs: reconcile guidance page and fix a stale doc comment
docs: work the tasks review pass-3 findings (spec 0037)
docs: work the tasks review pass-4 findings (spec 0037)
docs: correct the C-12 release note's description of the pre-fix rout…