I'm taking a look at our new ticket ro handler and the update root handler and between the two of these
they have pretty similar logic.
Request comes in.
We do some validation.
We make some changes to it take a document save it and then publish an event that's inside of update.
There is somewhere inside of new.
We do some validation.
We agree to take a document save it publish the event but you might notice a very small difference between
these two root handlers and that is the presence of the awake keyword on the publisher.
In each of them.
Inside of my new root handler I have the await keyword on ticket create a publisher but inside of update
I did not place that away.
Keyword is to highlight a very interesting little issue that we might run into once our application
starts to scale up.
So let's take a look at a couple of diagrams and really understand what the presence of that awake you
were does for us.
But here's what goes on behind the scenes inside of our ticket created handler so inside there we're
going to create a ticket document where then going to await that ticket being saved to the database.
And because we've got that a weak keyword on the ticket save call right here.
That means we're going to essentially sit around and wait for that record to be saved to the database
before we continue execution of this function.
After everything gets saved then we move on to the publisher and because we've got the awake word on
that publisher we're going to wait for the event to be published and that's and then eventually we're
going to send a response off to the user.
Now let's start to think about what would happen if something went wrong with this event publishing
process or for that matter if something went wrong with saving the record to the database as well.
So because we've got the awake keyword on there if anything goes wrong with either saving the record
to the database or publishing the event if we ever throw an error of any sorts from either those lines
of code that error is going to be caught and handled by our error handling middleware.
The error handling Middleware is going to inspect that error come up with some likely response or good
response and send it back to the user.
The point is if anything goes wrong the user is going to know about it they'll think about what would
happen inside of our update handler which does not have the awake word on the publisher in that scenario.
Here's what would go on.
So here's the update handler we have some logic inside there to make an update to the ticket document.
We then await saving the ticket to the document database so in that scenario once again if anything
goes wrong with saving the ticket.
Well errors can be thrown and it will be caught by our error handling middleware.
But then right after that we tried to publish any event to Nats and then immediately after that because
we do not await that publish.
So immediately after we attempt to publish that event we then send a response directly to the user so
we can really imagine inside this update.
Handler this line of code runs and then essentially in the next microseconds we then immediately send
a response back to the user.
That means that if anything goes wrong with publishing this event to nets we don't get any opportunity
to tell the user that some error occurred with the request though.
What starts to get really interesting however is whether we actually need to tell the user that something
went wrong with a published event.
If we think about this really back inside the new request handler it might sound like a pretty obvious
thing.
Hey let's await the event to be published so that the user knows hey everything went as expected but
does the user really care about this event being published.
All we're really doing here is adding in some arbitrary latency latency to our request as we have to
await our Nats client to reach out to that server or publish the event and get some response that says
hey you vent publish successfully so this really does add in some tiny bit of latency to the request.
Now what's way more relevant than all this stuff though.
Whether or not we await for the request or not is well what really happens behind the scenes.
If publishing any event fails let's expand on that a little bit more honestly.
Another diagram that's going to kind of show you that this entire idea of whether or not we await publishing
the event is not super relevant because there's actually a way bigger issue for us to start to think
about OK.
So here's a diagram I hear a little bit crazy.
It is similar nature to several we've already looked at.
So we're going to again imagine that we are thinking about some kind of banking application where we
have a transaction service and an accounts service as well.
The request is going to come in to the transaction service.
It will then be handled by some kind of route and alert to create a transaction and we can imagine that
this handler probably has some very similar logic inside of it to our ticket creation route handler
requests is going to come in.
It's gonna be validated processed there's going to be some code to add a transaction to a database presumably
into some kind of transaction collection and then immediately after that we're going to attempt to emit
an event that event will go over to that streaming server float over to the account service and so on.
So again I want to think about what would happen if something failed with emitting this event right
here.
How would we somehow communicate that back to the user.
What would the real impact on the application be though.
Here's what we're going to imagine we successfully saved the transaction to the database and then just
before we are able to emit an event describing the fact that the transaction was created what would
happen if we lost our Nats connection well if we can really think about it in terms of some banking
application we would have a very critical data integrity issue.
Think about what the user experience would be here.
A user would make a request to deposit some money we would then save.
A line item inside of some database thing that a deposit was accepted and that they deposited 70 dollars.
So that is firmly inside the database.
But then we never met this event describing the fact that the transaction was created and that means
that the user's account balance never gets updated.
So on the user side they would essentially submit some money or deposit some money.
Seventy dollars in this case they could probably then go to some transactions summary page something
it lists all the different withdrawals and deposits they have ever made.
And we would probably tell them that they have successfully deposited seventy dollars but because we
never communicated this event successfully over to the account service users account balance never gets
updated to plus 70.
So the user would see that they deposit seventy dollars but their account balance would potentially
still be zero.
And as you could imagine a user would look at this and say what the heck is going on.
You're telling me that deposit 70 dollars but my account doesn't actually have seventy dollars inside
of it.
So as you can see it's not really so much a question of hey how are we going to somehow tell the user
that publishing this event failed or do we want to add in that extra latency to the request.
That's kind of irrelevant.
What's really relevant here is how do we somehow capture the fact that we failed entirely to emit this
event and that we've got this critical data integrity issue between our two different services.
That's the real question here.
Now we understand this kind of big problem.
Let's take a quick pause.
We're gonna come back the next video and talk about one way of solving this.