Using the read model as a means for providing instant updates to the user

310 views
Skip to first unread message

dw

unread,
Sep 6, 2010, 2:54:43 AM9/6/10
to DDD/CQRS
Hi,

Basically, the problem is one of trying to provide users with an
absolutely instant update following their button press on the UI.
Lets say that the user makes an submission which isn't approved. They
then get taken back to a holding page which says it might take a while
for the submission to appear on the site. Being a user, they don't
actually read the page and immediately go to their list of
applications and notice it is not there. Would this not provide a
kind of bad user experience.

The way I was thinking of solving this problem (if it is a problem)
was introducing an intermediate record into the view model, which in
this case would be a temporary submission record. The UI would then
display this record like, "This submission is being sent to our
servers", and updated with AJAX or page refresh or something.

Do you guys think it would be bad to allow the UI to write to the
"read" model? Kind of like a poor separation of concerns.

Is this a problem I really need to solve? Lets say that the fact that
the submission is submitted on time is very important to the user, but
they always submit right at the last second. If they don't win that
submission, they immediately go to another submission and try to win
that one. Won't the seemingly non-existent submissions be upsetting
to them, since they will submit and immediately check status? I
appreciate they would kick up a lot of fuss if the site went down,
which quite frankly is the only alternative to queuing and
asynchronously handling the requests.

Thanks,
dave

dw

unread,
Sep 6, 2010, 2:56:25 AM9/6/10
to DDD/CQRS
Lol, I posted this and google took me to a holding page and said "your
post will appear momentarily" with a link back to the list of posts.
Although, I went back and it was there immediately.

Rinat Abdullin

unread,
Sep 6, 2010, 2:58:59 AM9/6/10
to ddd...@googlegroups.com
Yes. Google's approach is one of the answers))

You might also check this article on the timing and race conditions:
http://www.udidahan.com/2010/08/31/race-conditions-dont-exist/


Best regards,
Rinat Abdullin

Technology Leader at Lokad.com | Writer at Abdullin.com | Contacts

dw

unread,
Sep 6, 2010, 3:09:40 AM9/6/10
to DDD/CQRS
Yup, I've seen that article and it does help. But I feel that that
article addresses more the worry that submissions will never appear
because they are actually invalid, wereas my problem is more one of
latency and twitchy finger trigger users. I suppose I could try to
guarantee that all updates take place in less than a second for high
traffic periods. In my current redis setup I can handle 1000 events
per second, but I suppose with 10 redis servers on the same machine I
could handle 9000 events per second. Maybe it is just a case of
profiling.

seagile

unread,
Sep 6, 2010, 3:13:52 AM9/6/10
to DDD/CQRS
I think you have to ask your end-users. The question is not only if
but also why the immediate feedback is important. What is their intent
with that "pending" submission? Or do they rather want to be notified
when the submission is complete? At this point I think you are trying
to solve a problem that is yet unidentified. More questions are needed
to get to the bottom of things ...

Of course there is nothing wrong with contemplating how immediate
feedback would work in light of eventual consistency.

Regards,
Yves.

Scott Reynolds

unread,
Sep 6, 2010, 3:23:47 AM9/6/10
to ddd...@googlegroups.com

You don't need an,immediate record really do you. Can't you just fake the record client side....... once the command succeeds.

SteveG

unread,
Sep 6, 2010, 8:16:24 AM9/6/10
to DDD/CQRS
I was discussing this with someone. And later I thought:

What if something fails in the save downstream - they think they saved
it ok - now what - they find out later it failed?

So updating the UI sounds good, and yes, the UI needs to be updated
(IMO) - guess I need to read more about handling exceptions on the
command side downstream

On Sep 6, 3:23 am, Scott Reynolds <sco...@reynoldsphotography.com>
wrote:
> You don't need an,immediate record really do you. Can't you just fake the
> record client side....... once the command succeeds.
>

Udi Dahan

unread,
Sep 6, 2010, 8:20:27 AM9/6/10
to ddd...@googlegroups.com
If a command fails downstream, it is usually for "environmental" reasons (DB
or some web service was down) and not due to a logical failure. In this
case, command messages are moved to an error queue monitored by an admin,
who fixes the environmental problem, and then retries the command (by moving
it back to the original queue).

In other words, it just takes a bit longer for the command to be successful.

Cheers,

-- Udi Dahan

Scott Reynolds

unread,
Sep 6, 2010, 9:04:46 AM9/6/10
to ddd...@googlegroups.com

In my case, at the moment, the submitting of a command is syncronous into the event store so its guaranteed to have worked. If you go asynchronous then there's some other considerations but my feeling is commands need a success / failure results soon as possible after submission but my systems apply a lot of workflow / state related business rules and commands can be sent in via web services. I have to plan for command failure for business reasons.

Carl Hörberg

unread,
Sep 6, 2010, 12:10:28 PM9/6/10
to ddd...@googlegroups.com
2 ideas, either you send the user which submitted the command a email saying that the command failed and that they have to try again or something like that, or if you wan't the notifications to be integrated in the application you can utilities some thing like Socket IO (http://socket.io/) (or just poll a table with Command.Id and Success/Fail message), push the error message there and in your app you listen to that "socket" and shows the "command failed" via something like jGrowl (http://stanlemon.net/projects/jgrowl.html), could be kind of slick.. 

seagile

unread,
Sep 6, 2010, 1:07:05 PM9/6/10
to DDD/CQRS
As I said, you can contemplate all you want and discuss the merits of
each technical solution you can come up with. But I haven't heard any
"business" reason as to why the immediate feedback is required. From a
technical POV, either you fake the "submission", give it a "pending"
status (client side only), and use some kind of polling or callback
functionality to report status updates, or you block the user and wait
for the feedback to become available (if that outweighs him going off
to do the next thing).

On 6 sep, 09:23, Scott Reynolds <sco...@reynoldsphotography.com>
wrote:
> You don't need an,immediate record really do you. Can't you just fake the
> record client side....... once the command succeeds.
>

SteveG

unread,
Sep 6, 2010, 2:57:52 PM9/6/10
to DDD/CQRS
I can think of several.

Udi, how about validation - if that is done through business rules in
the domain model handled by a subscriber to a message - how do you
notify the user later that something they entered was invalid?

Ok, Seagile, so any command is treated as pending - do you send out a
notification when it was processed - are we using email or something
to tell the user?

Even in simple scenarios ? ie. I add an item to a shopping cart - is
it pending that item shows up in the shopping cart ?

So basically though I think I'm curious how everyone is handling this
'delay' between saving something and then seeing the results in query
a moment later - is email the new system, are you adding some sort of
'pending action' to the website - and where does that pending action
logic live? Obviously to show something pending, is that stored in
some non-delayed place ? memory ? Session state?

I'd like to hear more - I hear quick answers written in large paint
strokes, but I've never built a system where everything is solved by
large paint brushes :)

SteveG

unread,
Sep 6, 2010, 2:59:13 PM9/6/10
to DDD/CQRS
I should add, I'm looking at this from a web application perspective.

On Sep 6, 1:07 pm, seagile <yves.reynh...@gmail.com> wrote:

Udi Dahan

unread,
Sep 6, 2010, 3:26:44 PM9/6/10
to ddd...@googlegroups.com
Validation is performed client-side before the command is sent - the user
gets immediate feedback. The same is true for most reasons that a command
would fail (not including unique constraint violations, DB being down, etc).

Cheers,

-- Udi Dahan


-----Original Message-----
From: ddd...@googlegroups.com [mailto:ddd...@googlegroups.com] On Behalf
Of SteveG
Sent: Monday, September 06, 2010 9:58 PM
To: DDD/CQRS
Subject: [DDD/CQRS] Re: Using the read model as a means for providing
instant updates to the user

Tom Janssens

unread,
Sep 6, 2010, 3:47:08 PM9/6/10
to DDD/CQRS
Adding an item to a shopping cart should usually not fail... I would
fake it, and give a notification in the few lonely cases that it does
fail... (either by some kind of screen pop-up/ajax thing or on the
next request in case of web)...
If the read model does not update quickly enough, just add more
nodes :-)

In the more complicated business cases, where a user need to be able
to interfere in case of problems, I use something like saga's to
persist the state of the command; I split a command up in multiple
events/commands and persist the state in an aggregate root, so I do
consider this state to be a part of the domain model. I do not think
this is the usual approach, but it works perfectly for me... (in this
example there would be an extra command available on the AR :
SomeSaga.RegisterUser)
Please note that this requires you to build a read model around the
sagas as well...

I have to admit that I am currently using mostly real-time commands
and events in a non-distributed environment for winforms, so in most
of the cases my read model gets updated in real-time. In the rare case
that it does not get updated in real-time (i.e. remote server
requests), I use a special event that bubbles up to the UI... You
could have some kind of event handler which fills in some kind of
special session var for your webrequest and let your page respond to
it...

This might not be the perfect solution but it works perfectly for me.

Nuno Lopes

unread,
Sep 6, 2010, 3:48:46 PM9/6/10
to ddd...@googlegroups.com
Hi Udi,

> If a command fails downstream, it is usually for "environmental" reasons (DB
> or some web service was down) and not due to a logical failure.

I'm a but confused. If all you do is basic command validation, how can the system downstream only occasionally fails?

I mean I understand that trivial rule checks that can be made by a four year old, like checking the account balance before submitting but most of the systems I work with is not the case. Well maybe picking one rule as an example would work, but what makes it complex is not one or two rules, but the number of them.

For instance, take a game of chess. I could validate if the move is valid in the UI, after all considering one kind of piece the rule is quite simple. But considering the multiple types of pieces on the board, implementing them on the UI wouldn't just defat the purpose of having a domain model bellow?

Nuno


seagile

unread,
Sep 6, 2010, 4:22:38 PM9/6/10
to DDD/CQRS
I find it amusing at times that people think this functionality should
be there for each and every command. I'm willing to take a bet that
the number of aggregate types this functionality should be applied to,
is limited. Secondly, asynchronous notification is not required for
each and every aggregate. Not everybody is trying to build twitter/
facebook/linkedin.

On 6 sep, 20:57, SteveG <steven.gent...@gmail.com> wrote:

Udi Dahan

unread,
Sep 6, 2010, 4:29:22 PM9/6/10
to ddd...@googlegroups.com
Nuno,

We're not talking about "implementing them on the UI", but rather deploying
them in a way that is accessible client-side.

Cheers,

-- Udi Dahan


-----Original Message-----
From: ddd...@googlegroups.com [mailto:ddd...@googlegroups.com] On Behalf
Of Nuno Lopes
Sent: Monday, September 06, 2010 10:49 PM
To: ddd...@googlegroups.com
Subject: Re: [DDD/CQRS] Re: Using the read model as a means for providing
instant updates to the user

Polemann

unread,
Sep 6, 2010, 5:11:15 PM9/6/10
to DDD/CQRS
I don't understand commands not failing at all. Firstly I don't my
clients to pre-validate their commands and if there's time gap between
validation and sending the command may as well not have been
validated.

Im my case I have a standard web application with 1000+ active users
at any one time - they manage trouble tickets. One of the main issues
for the business was that when three techs open a ticket they each can
take ownership of that ticket (through their UI) but the business only
wants the first person to take ownership and the others to get the
update saying who had ownership and when it was taken.

I can't quite figure this out in this scenario. I can't use the read
model so I have to load my aggregate. How I would do this today is
submit the command and get a failure back from the business logic.
This is an expected command failure - built into the business rules
and I can't think of another acceptable solution.

stacy

unread,
Sep 6, 2010, 6:32:45 PM9/6/10
to DDD/CQRS
I certainly agree with others here that this should not be a technical
discussion at this point, but rather a discussion with users to see if
there is a problem and learn more about their expectations. Without
that input, it's a waste of time exploring this technically. Having
said that, I offer the following :)

"Being a user, they don't actually read the page and immediately go to
their list of
applications and notice it is not there."

Use cookies to store their submission info (id, title, date/time,
etc). Then show this info as "pending" in their list of applications.
Therefore no need to write to the read model; write cookies instead.

After the command is processed thru to the read model, then start
using the read model and expire the cookies. Based upon success/
failure of the command, as noted in the read model data, change
"pending" to the appropriate value. You can create a GUID id, on the
client, for use with the cookies, command param, and read model data.

Hope this helps!

Nuno Lopes

unread,
Sep 6, 2010, 6:57:49 PM9/6/10
to ddd...@googlegroups.com
Hi Udi,

Can you give is an example about how that is done beyond the trivial.

I mean against what data would that logic be used? If it is against the read part, considering that is de-normalized how is it served to these Procs/Specs?

Considering that such Procs/Specs are reused on the server side, how are aggregates turned into something for consumption by these Procs/Specs?

Nuno

Pedro Henriques dos Santos Teixeira

unread,
Sep 7, 2010, 12:16:25 AM9/7/10
to ddd...@googlegroups.com
On Mon, Sep 6, 2010 at 3:54 AM, dw <djwel...@gmail.com> wrote:
> Hi,
>
> Basically, the problem is one of trying to provide users with an
> absolutely instant update following their button press on the UI.
> Lets say that the user makes an submission which isn't approved.  They
> then get taken back to a holding page which says it might take a while
> for the submission to appear on the site.  Being a user, they don't
> actually read the page and immediately go to their list of
> applications and notice it is not there.  Would this not provide a
> kind of bad user experience.

Hello,

In our circular architecture, I've been using websockets so that the
browser client is also listening to some events, and can update state
accordingly.

I think it makes things richer and easier for the client, placing the
web UI as another listener with its own javascript event handlers.

Instead of persisting commands in a different way associated with my
event store, I actually have CommandReceived and CommandProcessed as
events also. With these events, and the actual target event of
interset (such as OrderCreated), I've implemented generic widgets for
showing progress in the UI.

Would that qualify as a sound solution for you?


(cheers)

Rick van der Arend

unread,
Sep 7, 2010, 12:08:44 PM9/7/10
to DDD/CQRS
Hurrah for using the term 'Circular Architecture'! :)
(I've written about this a couple of months ago)

But to the point: the result of performing a valid command should
always be some events, I think. I would try to get to better names
than 'blaBlaCommandSucceeded' and 'blaBlaCommandFailed'. These should
be events that mean something. In these cases, the user attempts
something and he/she knows it, the consequences of the attempt failing
probably already have their own UL names. In cases where a technical
difficulty is preventing command execution, this would need to be
handled in another way, not using domain events, I think. For async,
Udi's approach seems very elegant.

Regards,
Rick

On 7 sep, 06:16, Pedro Henriques dos Santos Teixeira
<pedr...@gmail.com> wrote:

Pedro Teixeira

unread,
Sep 7, 2010, 4:31:53 PM9/7/10
to DDD/CQRS
On Sep 7, 1:08 pm, Rick van der Arend <rvanderar...@gmail.com> wrote:
> Hurrah for using the term 'Circular Architecture'! :)
> (I've written about this a couple of months ago)

I've just read your blog post recently! and kudos for attempting to
extract the essence to a shorter name ;)
I think Greg's last post wqas also great in unifying the vision of
this all.


>
> But to the point: the result of performing a valid command should
> always be some events, I think. I would try to get to better names
> than 'blaBlaCommandSucceeded' and 'blaBlaCommandFailed'. These should
> be events that mean something. In these cases, the user attempts
> something and he/she knows it, the consequences of the attempt failing
> probably already have their own UL names. In cases where a technical
> difficulty is preventing command execution, this would need to be
> handled in another way, not using domain events, I think. For async,
> Udi's approach seems very elegant.
>

Recently, it seemed useful to also broadcast some "system events" (in
contrast to just some from a single business domain).

These can also be published to any clients interested in system/
application. The motivation is that it does enable better system usage
experiences, be it in browser or via APIs.

In practice, I considering the system itself, in a completely
different bounded context, as an aggregate root of some very especial
entities.

For example: UserLoggedIn, SystemWasTurnedOff, SystemWasUpgraded, as
well common stuff like MessageLogged, etc.


Would think this is an abuse of the technology to many other realms?
I'm really attracted to this uniform event-driven approach for most
things.


SteveG

unread,
Sep 7, 2010, 5:59:42 PM9/7/10
to DDD/CQRS
My customers say 'I entered a claim, why isn't the balance showing
update when I go the balance page'

"uh, well, sir, we are using a delayed command query pattern so your
updates won't show up now because we are offsetting the need for
instant gratification with better performance"

Customer: 'huh?'

"Yes, so we will show you a pending claim, and a pending balance, but
none of it is actually right because it's all stale data anyway"

:)

Pedro Teixeira

unread,
Sep 7, 2010, 7:26:18 PM9/7/10
to DDD/CQRS
On Sep 7, 6:59 pm, SteveG <steven.gent...@gmail.com> wrote:
> My customers say 'I entered a claim, why isn't the balance showing
> update when I go the balance page'
>
> "uh, well, sir, we are using a delayed command query pattern so your
> updates won't show up now because we are offsetting the need for
> instant gratification with better performance"
>
> Customer: 'huh?'
>
> "Yes, so we will show you a pending claim, and a pending balance, but
> none of it is actually right because it's all stale data anyway"
>
> :)

Steve,

Users are already used to wait while a request is "being
submitted...". For some interactions, you can still show a
"processing..." feedback status, despite the CQRS pattern being used
behind the scene.

What I've tried to mentioned previously, was that, one should strive
to be event-oriented in the UI as well, so users *can* be notified
about interesting events as soon as possible. Polling (either by the
user or by the system) can be avoided.


There are plenty of user inputs which are genuinely asynchronous. If
you have mobile UIs as part of your solution, you'll see that's pretty
common as well.


(cheers)














Elliott O'Hara

unread,
Sep 7, 2010, 8:22:01 PM9/7/10
to ddd...@googlegroups.com
Steve,
I just went and looked at the online banking for Bank Of America. 

It says "processing" by a charge, but the charge is the gas I just bought and used to get home from work...How is it "processing"?
I didn't even think there was an issue. Even though I didn't get "instant gratification".

In fact, I think that it's awesome that they're showing me "processing" charges.

You should probably work on the way you communicate with your customers a little bit. 

/E

Udi Dahan

unread,
Sep 8, 2010, 1:08:23 AM9/8/10
to ddd...@googlegroups.com
My customers say 'I entered a claim, why isn't the balance showing
update when I go the balance page'

"Your claim hasn't been approved yet - when it will be approved, you'll see
your balance reflect that"

On the balance page, you'll likely show the series of transactions that
brought it to that state, and the newest claim won't appear in that list.
You can also include a statement saying that "transactions may take up to an
hour to appear on this page". This historically was the product of
batch-based integration between disparate systems but users have already
gotten used to it, so why not exploit that.

Cheers,

-- Udi Dahan


-----Original Message-----
From: ddd...@googlegroups.com [mailto:ddd...@googlegroups.com] On Behalf
Of SteveG
Sent: Wednesday, September 08, 2010 1:00 AM
To: DDD/CQRS
Subject: [DDD/CQRS] Re: Using the read model as a means for providing
instant updates to the user

Udi Dahan

unread,
Sep 8, 2010, 1:14:34 AM9/8/10
to ddd...@googlegroups.com
Nuno,

The data used to perform that client-side logic would come from the
persistent view model. The fact that that is denomralized isn't relevant -
the structure of the data held there is designed to be suited to these kinds
of client-side queries.

However, these queries aren't "reused" on the server side, the only reason
to do that would be because we don't trust clients. The way that that is
handled is to have all commands from un-trusted clients be piped through our
own trusted client which performs those checks, and only if they pass does
it let them through to our server.

Cheers,

-- Udi Dahan


-----Original Message-----
From: ddd...@googlegroups.com [mailto:ddd...@googlegroups.com] On Behalf
Of Nuno Lopes
Sent: Tuesday, September 07, 2010 1:58 AM
To: ddd...@googlegroups.com
Subject: Re: [DDD/CQRS] Re: Using the read model as a means for providing
instant updates to the user

Udi Dahan

unread,
Sep 8, 2010, 1:21:46 AM9/8/10
to ddd...@googlegroups.com
The domain you're describing is a non-collaborative one - it is competitive.
As such, CQRS isn't the best fit - you want first-one-wins concurrency here.
That being said, the domain can be analyzed differently aligning it with the
principles of CQRS:

After a user finishes working on a ticket - sending a command CloseTicket,
the system then stores that that user is free for another ticket and decides
which ticket to allocate to which user. This removes the competitive nature
of the domain and doesn't require high synchronization between users any
more. As such, the list of open tickets no longer needs to be very up to
date as it is primarily a report for supervisors. We can also have the
system flag tickets that haven't been resolved by a certain period of time,
automatically escalating them to supervisors.

In short, don't force fit CQRS into a given system definition. CQRS is
*part* of the system definition.

Cheers,

-- Udi Dahan


-----Original Message-----
From: ddd...@googlegroups.com [mailto:ddd...@googlegroups.com] On Behalf
Of Polemann
Sent: Tuesday, September 07, 2010 12:11 AM
To: DDD/CQRS
Subject: [DDD/CQRS] Re: Using the read model as a means for providing
instant updates to the user

Rick van der Arend

unread,
Sep 8, 2010, 2:27:55 AM9/8/10
to ddd...@googlegroups.com

By the way, does anybody contest the need for domain and technical events? I guess not, because a lot of applications already work with technical (logging) events. But if anybody has a different view on this, I'd like to hear it..

Regards,
Rick

---
Verzonden vanaf een mobiele telefoon

Op 8 sep 2010 01:26 schreef "Pedro Teixeira" <ped...@gmail.com>:

On Sep 7, 6:59 pm, SteveG <steven.gent...@gmail.com> wrote:

> My customers say 'I entered a claim, w...

dw

unread,
Sep 8, 2010, 2:42:13 AM9/8/10
to DDD/CQRS
I do like the idea of system events, if only for the purposes of
reporting stats on your applications.

Nuno Lopes

unread,
Sep 8, 2010, 4:41:38 AM9/8/10
to ddd...@googlegroups.com
Hi Udi,

Thank you for your feedback.

> However, these queries aren't "reused" on the server side, the only reason
> to do that would be because we don't trust clients. The way that that is
> handled is to have all commands from un-trusted clients be piped through our
> own trusted client which performs those checks, and only if they pass does
> it let them through to our server.

That is what we do here for about 5 years with no CQRS, so I was expecting an improvement. You see, we use MVC on the Web and we developed our own UI framework.

1) We do simple validation on the web browser (simple mandatory logic based on what is selected)

2) On the web server we have what we call a View Model. In this model we store more then is presented to to deeper validations.

3) When everything is valid we then send these data to a façade that call the web services. Each of these web service the can use a domain model bellow or whatever. When things get slow, we just reference the "domain model" dll directely.

In most cases we don't call web services in as synch.

I believe that sometimes are my expectations over CQRS that cloud my reasoning over what is written. This architecture comes with its own overhead.

What I think is that CQRS on top of a Messaging BUS is what makes this thing scale better then what we already do. Because as far how data flows is more or less the same.

Furthermore, I think Aggregates play a major part on it too.

Cheers,

Nuno
PS: How "commands" (web service calls) do fail

Nuno Lopes

unread,
Sep 8, 2010, 4:42:49 AM9/8/10
to ddd...@googlegroups.com
Udi,


> This removes the competitive nature
> of the domain and doesn't require high synchronization between users any
> more.

+1. You can learn a lot about turn based games such as Chess.

Nuno
PS: Maybe at least one person will understand this drift.

Reply all
Reply to author
Forward
0 new messages