Why lot's of developers use one-way command messaging (async handling) when it's not needed?

4,051 views
Skip to first unread message

Burtsev Alexey

unread,
May 9, 2012, 6:56:00 AM5/9/12
to ddd...@googlegroups.com
I find lot's of code where people use async command handling or one way command messaging without any reason to do so (they are not doing some long operation, they are not executing external async code, they do not even cross application boundary to be using message bus). Why do they introduce this unnecessary complexity? And actually I haven't seen a CQRS code example with blocking command handlers so far, thought it will work just fine in most cases.

Oddly I find this especially often in ASP .NET WEB environment, where people begin to use AJAX, e-mail, or any other back channel to inform client on command result.
As a fresh example of this is Microsoft Patterns & Practices CQRS Journey, where they use async command handling, and then use ugly while(NotDone) blocking loop in page controller.

Yevhen Bobrov

unread,
May 9, 2012, 8:51:13 AM5/9/12
to ddd...@googlegroups.com
Alexey,

You're absolutely right. I see this everywhere. Similar abuse happens with Sagas.
If you don't really need command to be executed asynchronously - don't do it.

In our app we execute all user-created commands synchronously.
The only commands which got executed asynchronously are system-generated commands.

In fact I don't believe that there is such thing as asynchronous command at all, because the sending agent is usually interested in the result of its execution.
So when the command is created as a result of user initiated action - it's exactly this case. You just execute it and immediately communicate the status back - ok or exception.

The other case, is when the command got created by the system, in response to some event. Because event handling is asynchronous by nature, ie fire-and-forget, so all commands generated in response to this event will also be asynchronous as a consequence.

In fact, even Greg admitted that here

Yevhen

Burtsev Alexey

unread,
May 9, 2012, 9:54:05 AM5/9/12
to ddd...@googlegroups.com
I found Greg's answer to this "question" at his CQRS class video at 185:35 minute.

Werner Clausen

unread,
May 9, 2012, 9:55:11 AM5/9/12
to ddd...@googlegroups.com
I guess the issue here, is that not everyone agrees on when it is needed! I'm sure that if you ask the P&P guys, they'll have a reason for that specific choice?
 
--
Werner

Raoul Duke

unread,
May 9, 2012, 1:18:35 PM5/9/12
to ddd...@googlegroups.com
On Wed, May 9, 2012 at 6:54 AM, Burtsev Alexey
<brokenpi...@gmail.com> wrote:
>> cross application boundary to be using message bus). Why do
>> they introduce this unnecessary complexity? And actually I haven't seen a

yeah. e.g. see:
https://github.com/laforge49/JActor

"Two-way messaging is so much faster than 1-way messaging that it is
[even] practical to use
2-way messages when only 1-way messages are needed."

Greg Young

unread,
May 9, 2012, 6:00:01 PM5/9/12
to ddd...@googlegroups.com
actually I said that an asynchronous command doesn't exist :) its
actually another event. If I must accept what you send me and raise an
event if I disagree, its no longer you telling me to do something. Its
you telling me something has been done. This seems like a slight
difference at first but it has many implications.
--
Le doute n'est pas une condition agréable, mais la certitude est absurde.

Daniel Cazzulino (kzu)

unread,
May 10, 2012, 1:55:55 PM5/10/12
to ddd...@googlegroups.com
That's just a (small) optimization to have a better uex. It's not required, and certainly it could be the client page waiting instead (which we also do). When the messaging loop is fast enough, the user experiences an instantateous update. That's a good thing, I think.

Julian Dominguez

unread,
May 10, 2012, 9:35:17 PM5/10/12
to ddd...@googlegroups.com
Correct, most of the times by the time you hit the controller action, the data should already be processed (and the read model up-to-date), and there will be no wait at all. It's not like we are sending a command, and in the same thread waiting for a response. We send the command, we redirect the user to a different page (using the PRG pattern) and then render the UI, which should have the new data available. If it's still not available we do the ugly loop for a very short time. If after that short time the data is still not available, we return and notify the user.
This is for just one screen, where we absolutely need the processing to have happened before moving to the next step. With some other commands we just don't care if the read model is already updated or not.
Having said that, we are already considering doing synchronous processing of the commands that do not require a single writer (an example in the conference sample where async processing becomes handy is when there is heavy competition for the last few seats of a conference, where we do not allow overbooking).

Does this make sense?

Julian Dominguez
patterns & practices

Henrik Feldt

unread,
May 15, 2012, 5:15:08 AM5/15/12
to ddd...@googlegroups.com
But if you're showing 'the way' to do it, why not use an Async await so that you don't bind up the web server worker thread while doing it?

@yreynhout

unread,
May 16, 2012, 3:06:02 AM5/16/12
to ddd...@googlegroups.com
Indeed, go get your mustard Chez SignalR, like I did :-) (cfr. HttpTaskAsyncHandler)


On Tuesday, May 15, 2012 11:15:08 AM UTC+2, Henrik wrote:
But if you're showing 'the way' to do it, why not use an Async await so that you don't bind up the web server worker thread while doing it?

Scott Coates

unread,
Sep 4, 2012, 8:30:46 PM9/4/12
to ddd...@googlegroups.com
How do you guys achieve this synchronously? Are you using NSB or MassTransit? Are you using any ES such as JOliver.Eventstore? At first glance it looks like these libraries are almost expect asynchronous executions and nothing else?

João Bragança

unread,
Sep 5, 2012, 4:57:37 AM9/5/12
to ddd...@googlegroups.com
How are you hosting your application? With either Web or WCF you are
already is a request / reply (sync) world. Register command handlers
by type in a local bus and you are good to go.

Scott Coates

unread,
Sep 5, 2012, 2:40:28 PM9/5/12
to ddd...@googlegroups.com
The web side sends messages and a service responds. We're using MassTransit. But it doesn't really matter how I'm hosting the app - I'm asking how they achieve sync calls because MassTransit and EventStore by their very nature are async.

Yevhen Bobrov

unread,
Sep 5, 2012, 3:06:41 PM9/5/12
to ddd...@googlegroups.com
We just don't use muddleware to execute commands synchronously. Simply execute it on a web server within a request.

Sent from my iPhone.

5 сент. 2012, в 20:40, Scott Coates <scott.c...@gmail.com> написал(а):

Kasey Speakman

unread,
Sep 5, 2012, 6:18:25 PM9/5/12
to ddd...@googlegroups.com
Myself, I have a MVC Controller action to receive the command (from nearly any source that can do an HTTP POST):

        [HttpPost]
        public ActionResult Execute([ModelBinder(typeof(CommandModelBinder))] ICommand command)
        {
            CommandResult result = CommandDispatcher.Dispatch(command);
            return Json(result);
        }

The custom model binder (CommandModelBinder) takes care of shoving the POST information into an appropriate .NET object, using reflection and a type hint from the POST data. CommandResult has 2 properties, an enum for success / failure, and a string message. ICommand has a Validate method which also returns CommandResult. The Dispatcher is basically the "local command bus":

        readonly Dictionary<Type, object> commandHandlers;

        public CommandResult Dispatch(ICommand command)
        {
            CommandResult result = command.Validate();
            if (result.Status > ResultType.Error)
            {
                try
                {
                    Invoke(command as dynamic);
                    result = new CommandResult(ResultType.Success);
                }
                catch (MyCustomDomainException ex)
                {
                    result = new CommandResult(ResultType.Error, ex.Message);
                }
            }
            return result;
        }

        private void Invoke<T>(T command) where T : ICommand
        {
            IHandlesCommand<T> handler = (IHandlesCommand<T>)commandHandlers[typeof(T)];
            handler.Handle(command);
        }

All the reflection junk to initialize the commandHandlers variable is in the omitted constructor. But it's basically as you would expect: looking through the assembly for all classes that inherit IHandlesCommand, getting the generic type parameter, and making a dictionary of it all.

In my system, the event handlers are run asynchronously. (I just queue them to run on the ThreadPool.) At that point, I know that the command has run successfully, and there's really no need for me to wait any longer before returning a result.

This isn't really a distributed application, and it's not setup for massive scale, although it could be modified to do so if the need arises. Instead, I wanted to take advantage of a) messaging to divide work and have multi-platform capability in the future (especially client-side), b) CQS to avoid the domain bloat that occurs when using the domain model for a view model (or alternatively, to avoid a lot of mapping code maintenance), and c) use DDD to deal with complex requirements.

I think a lot of the talk on async commands has to do with distributed systems, because the commands may literally go to a queue to await execution on some remote machine that the client may not know ahead of time. At that point, it could be pretty challenging to wait for commands synchronously. Queued commands where only one command per AR runs at a time have pretty nice advantages as far as avoiding locking performance overhead and resolving concurrency conflicts. These are nice architectural properties for that class of application, but it's not what many of us need to worry about preeminently.
Message has been deleted

Bennie Kloosteman

unread,
Dec 12, 2012, 2:29:06 AM12/12/12
to ddd...@googlegroups.com
I must admit im still working on this but in my view is CQRS is more for  complex business , large or high transaction volume apps ( eg much greater than  1000 / sec) .. I dont see it justified in other cases 

In these environments 

- A Async command  into the domain with events ( which can be caught ) allow for better decoupling . 
- 90% of commands should pass after validation so error returns are few .. So in most cases you validate the command synchronously  then send it async and you will only have a few errors which will have be relevant to the business anyway eg take the order and try to pay later. 
- The web is asynchronous anyway. Leaving a connection hanging while you do DB stuff is not that great .
- You can use Async controllers (MVC) or an async web system if the need arises with higher throughput. 
- For large systems clients will have the ability to catch errors or messages anyway ( pick your poison  , long poll , RXBus  etc . So its trivial hooking this up to a  business event. 


On Wed, Dec 12, 2012 at 11:03 AM, Brian Hall <br...@hallmanac.com> wrote:
Thanks for your input on how you were handling commanding and eventing inside an ASP.NET MVC application. I've recently been thinking through the exact same scenario for a project that I just began and was coming to the same conclusions you listed above. It helped my confidence to see someone outside of my little bubble thinking similarly. :-) 

Greg Young

unread,
Dec 14, 2012, 9:54:22 AM12/14/12
to ddd...@googlegroups.com

thats because you are just getting into the ideas. there are loads of other applicable places, what about occasionally connected clients as an example...

Greg Young

unread,
Dec 14, 2012, 9:55:13 AM12/14/12
to ddd...@googlegroups.com

simplecqrs? its blocking (ack nak)

Reply all
Reply to author
Forward
Message has been deleted
0 new messages