WEBVTT

00:00.380 --> 00:05.930
Now we can also see the rest of our microservices have started up successfully and we can go back to

00:05.930 --> 00:10.380
Postman and make sure all of our functionality is still working as expected.

00:10.400 --> 00:15.110
So I'll go ahead and create a new user so that we start from scratch.

00:15.110 --> 00:19.550
So I'll create a new user by targeting our auth service slash users route.

00:20.030 --> 00:21.890
I've gone ahead and created the user.

00:22.220 --> 00:29.570
I'll go ahead and log in with its credentials, so make sure I have the correct email test user to I

00:29.570 --> 00:31.250
have my JWT set.

00:31.640 --> 00:39.080
So now if I launch a request at localhost 3000 slash reservations to send a post request to create a

00:39.080 --> 00:46.490
reservation with our typical reservation payload, I can see if I send this request off, I come back

00:46.490 --> 00:48.530
with a 201 created response.

00:48.530 --> 00:51.620
So our reservation has been successfully created.

00:51.620 --> 00:58.520
And then if we look at our Stripe dashboard, I'll go ahead and refresh and we can see we have a new

00:58.620 --> 01:02.160
$45 payment that has just been processed.

01:02.160 --> 01:08.430
And if we go to our email provider, you can see I have a new email from Sleepers saying that my payment

01:08.430 --> 01:15.630
has completed successfully so we can see that our microservices are working just as they did before.

01:15.630 --> 01:20.610
Even though we swapped out our transport layer, we didn't have to change any of our underlying code

01:20.640 --> 01:23.970
thanks to the nestjs microservice abstraction.

01:23.970 --> 01:31.380
So now that we have rabbitmq set up, let's show the differences in our retry logic by going to the

01:31.380 --> 01:36.360
payments controller again and we'll rethrow that error in the same spot.

01:36.360 --> 01:44.270
So let's go ahead and throw that error when we create the charge and see what happens now.

01:44.280 --> 01:51.450
So now after Recompiling, if we try to create a reservation again, we get that 500 internal server

01:51.450 --> 01:54.600
error as we expect from the reservation service.

01:54.960 --> 02:04.950
Now if we run Docker container LS in another terminal and get the container ID for the payment service,

02:04.950 --> 02:10.770
let's go ahead and restart it by running Docker container restart and then pasting in the container

02:10.770 --> 02:15.030
ID so that our container restarts.

02:15.030 --> 02:20.640
So now that our container restarted, you can see that it didn't try to reprocess that failed message

02:20.650 --> 02:22.350
it originally received.

02:22.350 --> 02:29.160
And that's because by default, Nestjs is automatically acknowledging all the messages that we process

02:29.160 --> 02:31.860
in Rabbitmq back to the broker.

02:31.860 --> 02:38.310
So we actually have to explicitly tell it to not automatically acknowledge all these messages by going

02:38.310 --> 02:39.870
back to the main.ts.

02:39.870 --> 02:46.890
And in the options there's a property called Noac that if we set to false, that means that we won't

02:46.920 --> 02:50.580
automatically AQE and we need to do this ourselves.

02:50.850 --> 02:53.340
So let's go ahead and see the effect of this.

02:53.340 --> 02:59.910
After our container restarts, we will send a another message to create a failed reservation.

02:59.910 --> 03:02.590
So that this message gets retried.

03:02.610 --> 03:08.640
I'll go ahead and send the failed message off and we can see we have the 500 in reservations and the

03:08.640 --> 03:10.200
error in payments.

03:10.200 --> 03:16.560
So now we'll go ahead and run that same command where we restart the payments container, look at the

03:16.560 --> 03:22.730
container ID and run docker container restart and go ahead and restart it.

03:22.740 --> 03:26.910
So let's see the behavior now as payments restarts.

03:26.910 --> 03:34.770
So immediately after starting up here, you can see that it actually retried the message and ran into

03:34.770 --> 03:38.190
the same exact error that we had originally.

03:38.190 --> 03:44.340
So this is very powerful because unlike the TCP microservice, we actually have state here because of

03:44.340 --> 03:45.390
our queues, right?

03:45.390 --> 03:51.240
So after this message fails to get reprocessed, the broker never receives the Ack and next time we

03:51.240 --> 03:56.160
ask for the next message, well, we get that failed message and we can replay it.

03:56.160 --> 03:58.800
Maybe if a service was down, we can retry it.

03:58.800 --> 04:00.900
And that way we don't lose the message.

04:00.900 --> 04:05.340
So this is a big benefit of using asynchronous messaging like Rabbitmq.

04:05.790 --> 04:12.300
Additionally, we also have the added benefit of now having a queue so that if we can't process all

04:12.300 --> 04:17.700
these messages at once, like in TCP, we'll be hit with a bunch of requests at once.

04:17.700 --> 04:23.490
Instead, with a queue, we can process our messages in a controlled fashion so that we don't overload

04:23.490 --> 04:27.930
our container with work because we have this maintain state of messages.

04:28.200 --> 04:32.670
So this is another big benefit of using async messaging like Rabbitmq.

04:33.060 --> 04:40.500
And thanks to Nestjs abstracted microservice, we don't really need to change out a lot of functionality

04:40.500 --> 04:41.740
as we've seen.

04:41.760 --> 04:48.690
Now I want to show you how we can actually acknowledge these messages manually in case we want to handle

04:48.690 --> 04:49.560
this on our own.

04:49.560 --> 04:52.410
Maybe persist the message to a dead letter queue.

04:52.440 --> 04:59.880
We actually can get access to the current message context by using the add context decorator and.

04:59.900 --> 05:03.110
And this will be of type rmq context.

05:03.140 --> 05:10.820
So now that we have access to the rabbitmq context, we need to get access to the channel by calling

05:10.820 --> 05:14.420
context dot get channel ref.

05:14.930 --> 05:20.780
And then we need to get access to the original message, which is just the message that we are currently

05:20.780 --> 05:21.200
on.

05:21.200 --> 05:24.590
We can call context dot get message.

05:25.400 --> 05:30.920
So this can also be useful if we need to explore any of the other metadata on the message.

05:31.430 --> 05:34.520
However, we're interested with actually asking the message.

05:34.520 --> 05:42.110
So if we call channel dot ACC and then pass in the original message, we will actually acknowledge our

05:42.110 --> 05:42.680
message.

05:42.680 --> 05:49.130
And this won't get repeated because we're asking the message and then we're throwing an error.

05:49.130 --> 05:51.860
So let's go ahead and actually see what this looks like.

05:51.860 --> 05:58.850
Now after our container restarts, you can see that it reprocesses the message.

05:58.910 --> 06:01.560
However, now we've actually act.

06:01.580 --> 06:08.040
So if we try to restart the container like we did before, let's go ahead and see what happens.

06:08.060 --> 06:14.180
I'll take the container ID from payments and go ahead and restart this container.

06:14.180 --> 06:20.840
We should expect to see the message not get reprocessed any longer because we acknowledged it before

06:20.840 --> 06:22.090
we threw an error.

06:22.100 --> 06:24.520
So let's see as it starts up now.

06:24.530 --> 06:30.930
So payments has started up and you can see it no longer processed that message because we acknowledged

06:30.930 --> 06:31.230
it.

06:31.230 --> 06:35.580
It took it off of the queue and there was no longer the message to process.

06:35.580 --> 06:40.860
So we can have much more fine grained control over what messages we want to acknowledge, when we want

06:40.860 --> 06:41.850
to acknowledge them.

06:41.850 --> 06:48.360
And we can essentially replay these messages whenever we want by manually acknowledging which is super

06:48.360 --> 06:49.290
powerful.

06:49.290 --> 06:52.860
And finally, I'll just go ahead and remove the error now.

06:52.860 --> 06:55.170
So now we're still acknowledging the message.

06:55.170 --> 07:00.290
As soon as we return the data back to the caller, which is what we want to do.

07:00.300 --> 07:07.170
So I hope this has been a useful lecture for you to understand how we can easily plug in different transports

07:07.170 --> 07:14.820
into nestjs microservices and take advantage of the asynchronous messaging so that we can implement

07:14.820 --> 07:20.910
retries by re queuing messages and to make sure that we don't have to process all of our messages at

07:20.910 --> 07:23.820
once, we can take advantage of a queue.
