Ohhh that's where CQRS came be useful in implementing that sync/async system. The notification part of your video is interesting too, I'll have to check out SignalR now.
If you haven't already, check out this video where I show using SignalR with Event Driven Architecture to do exactly that. ua-cam.com/video/Tu1GEIhkIqU/v-deo.html
Not sure which implementation of rpc you're referring to, but grpc can do more than just unary calls. If you do a streaming call, you have the ability to perform similarly to message queues too. I've used it in a weakly consistent afs implementation. Server and client have an open a steam and a client local iostat watch thread will propagate file level changes back and forth. Then the client or server can do their own logic to pull from each other. You can even implement a rwmutex, technically. This video, to me, seems more like the paradigm of sync vs async. When to use one or the other. In sync, you can write your code to check if service is online or have expectation back-offs etc, but the result is the same work is or is not getting done. It's the human aspect that you're trying to address here, simply put. Is it better to know your request didn't get completed right now or wait to find out that it didn't get done. It will depend on the use case, if it's something like adding a calendar entry, I can see how someone would really want to know if their entry got added to their calendar but if it's something like a refill request on a medication, I can see why it would make sense to check back or get notified. This would really be determined by the domain of the application. Nonetheless, you've given me some ideas to improve the afs I wrote a while back.
"A service should have all the data in needs to operate autonomously. It shouldn't have a make a synchronous call to another service to get data"... AWESOME. This is such a simple concept yet most of the codebases I see have strung together 5 to 6 http calls between different "microservices" in order to do a very simple operation. Out of those code bases, most of them usually invoke the first call in the chain from the web request thread... and some of them even combine things like transactional resources (db calls), with non-transactional calls (a broker like RabbitMQ) making assumptions about all operations being able to magically commit in an ATOMIC fashion. Not only are the chained calls blocking, but there are multiple chances for failure just on the http/wire level like you mentioned. Add for trans/non-trans resource in same logical operation, and it really becomes a nightmare to try to troubleshoot when this stuff blows up, or to untangle it in order to refactor.
What you described is what I suspect is the majority of "microservices" implementations. We'll swing back to Monoliths sooner rather than later because of the hot mess that is a distributed ball of mud. Folks will rediscover atomic transaction. Then we will be back to having enormous schemas that are unmanageable and have a ton of coupling at the database level.. then the cycle continues. Sorry I'm cynical 😆
This man deserves more subs! Thanks man, been watching all of your videos for a week now. I'm learning a lot. keep it up. greetings from the Philippines.
Hi Derek -- I recently came across your channel and have been binge watching your videos. They're great! Your straightforward, relaxed approach to clearly explaining various software architecture concepts is refreshing. Keep it up!
Good info and to the point. Congratulations! Wanted to make you a question though. In your example showing AWS VM's, you stop the active vm and in this particular case you can show the actual state of the vm. But how would you do this if you want to add a new client from the UI client to your database for example?. Yes, you said that you could notify the client saying "Hey! everything is ok" and create the message, send it to the broker and then trough signalr, push notifications or whatever notify the client. But, isn't this odd? When I add a customer in my accounting program (for example) I want to see the client right after I add it. How would you go for a case like this if you wanted to use async communication instead of synchronous? This leads me to think that it would be sensible to use messaging just for long running operations where the user really expects some delay between his action and the final result as in your AWS vm example. Thanks in advanced.!
Yes, there are certain operations where a end user expects to see the result. In your example if you add a customer to your accounting program, that wouldn't be asynchronous. However, let's say you were uploading some receivables via a file into your accounting system. That likely could be asynchronous where the upload occurs and is put into blog storage. Then a message is enqueued with a reference to the blog storage ID/file where it then asynchronously processes the file.
I also left out asynchronous request/response. I've done videos about Microsoft Orleans and Virtual Actors (cloud native objects) way back and plan to do more in the near future so stay tuned.
Hi nice video. The service that consume message from broker is a background job or what ? if after save data to db then produce message to broker failed, what should we do ?
Also, there is a known thing, that duplication of data is bad in any case. And MSA tends to duplicating required data for particular service. Could you please find some arguments which will help to convince others, that spreading data via events is good practice for MSA ?
Again awesome and very useful topic! Would you mind publishing a working project(end to end) for same example where command is being failed and passed too.
Ya I probably have something close in another sample project. Check out the one for eShopOnWeb related to this video: ua-cam.com/video/bxGkavGaEiM/v-deo.html
Could you please clarify, when you say send a message via broker, do you mean to send a query via broker to a queue and senders is waiting for a response message listening to another queue ? Is async\await for http request is not enough ? what for do you a queue in this case?
The real hard part for me, and I just can't find many people elaborating on that, is how to make services really independent. e.g. I'm now breaking a monolith into 10-20 services. There are a lot of dependencies between domains. A lot of SQL JOINs that would instantly be translated into a synchronous HTTP/gRPC call to a secondary service (within the same user request). Those can't be asynchronous, but splitting them also doesn't make sense. Do I need a complete re-design?
I'd say re-align and start defining boundaries. One way to start is breaking off as small as you can, a piece that has minimal coupling to anything else.
This was very helpful thanks you just got a sub. One question i have is so what happens when the placing of an order actually fails later and we already said order was placed. For example there is no quantity for the order ordered.
Depends on the business. The product may be back ordered in which a purchase order to the vendor is already placed. Maybe the customer is notified and an expected delivery date. If there is no future product to arrive via any PO, maybe the order is just refunded. This really isn't a technical concern it's more of a business concern.
Hi Derek. I just wanted to ask a quick question if you don't mind. I am currently working on an event-driven architecture project, where one of the services is a chat-service, based on CQRS pattern. My question is, for the initial state query, meaning loading the previous messages, would you suggest making it asynchronous or synchronous, based on your opinion/prior experience? Thank you for your time.
Hi Derek, I recently started working at a new company, where the services communication is done with rabbitMQ RPC. As far as I understand this is an async communication pattern via messaging queue, but it called RPC so does it fall under the RPC pattern? I would really appreciate to get your opinion about rabbitMQ RPC in general :)
It's more about if the calling code is blocking. Meaning if the calling code sends a message to a queue, then is blocking waiting to pick up a response message in a different queue. And not until it gets a response (or times out) does it continue down the callstack. I'd avoid this where possible and handle replies asynchronously (non-blocking). If you haven't already check out this video I did on async request/response ua-cam.com/video/6UC6btG3wVI/v-deo.html
Hi sir, i encountered a project which I think is a distributed monolith app. They use Rest http to call one service to another. What is your opinion on that?
Since you mentioned about pushing a notification to the client using Signal R,the first thing that came to my mind was the number of open connections we will have during peak traffic. If we have hundreds of thousands of users all connected using signal r, won't our service take a massive performance hit? Also then does it make sense to have an independent push notification service that can be independently autoscaled as per load?
Of course context matters. If you have that many active concurrent users, you might not want to. Or perhaps you use something like Azure SignalR Service to scale it and have dedicated separate processes to consume events from completed commands then push those to SignalR. It really depends on the context on how to implement it and what makes sense.
@@CodeOpinion The individual HTTP req. Is of course synchronous (just as enqueuing a message with one is), but when I say "async HTTP calls" I mean, making a req which immediately returns an waiting for the result in form of a callback.
Ohhh that's where CQRS came be useful in implementing that sync/async system. The notification part of your video is interesting too, I'll have to check out SignalR now.
If you haven't already, check out this video where I show using SignalR with Event Driven Architecture to do exactly that. ua-cam.com/video/Tu1GEIhkIqU/v-deo.html
Not sure which implementation of rpc you're referring to, but grpc can do more than just unary calls. If you do a streaming call, you have the ability to perform similarly to message queues too. I've used it in a weakly consistent afs implementation. Server and client have an open a steam and a client local iostat watch thread will propagate file level changes back and forth. Then the client or server can do their own logic to pull from each other. You can even implement a rwmutex, technically.
This video, to me, seems more like the paradigm of sync vs async. When to use one or the other. In sync, you can write your code to check if service is online or have expectation back-offs etc, but the result is the same work is or is not getting done. It's the human aspect that you're trying to address here, simply put. Is it better to know your request didn't get completed right now or wait to find out that it didn't get done. It will depend on the use case, if it's something like adding a calendar entry, I can see how someone would really want to know if their entry got added to their calendar but if it's something like a refill request on a medication, I can see why it would make sense to check back or get notified. This would really be determined by the domain of the application.
Nonetheless, you've given me some ideas to improve the afs I wrote a while back.
"A service should have all the data in needs to operate autonomously. It shouldn't have a make a synchronous call to another service to get data"... AWESOME. This is such a simple concept yet most of the codebases I see have strung together 5 to 6 http calls between different "microservices" in order to do a very simple operation. Out of those code bases, most of them usually invoke the first call in the chain from the web request thread... and some of them even combine things like transactional resources (db calls), with non-transactional calls (a broker like RabbitMQ) making assumptions about all operations being able to magically commit in an ATOMIC fashion. Not only are the chained calls blocking, but there are multiple chances for failure just on the http/wire level like you mentioned. Add for trans/non-trans resource in same logical operation, and it really becomes a nightmare to try to troubleshoot when this stuff blows up, or to untangle it in order to refactor.
What you described is what I suspect is the majority of "microservices" implementations. We'll swing back to Monoliths sooner rather than later because of the hot mess that is a distributed ball of mud. Folks will rediscover atomic transaction. Then we will be back to having enormous schemas that are unmanageable and have a ton of coupling at the database level.. then the cycle continues. Sorry I'm cynical 😆
Great explanation on why and when to use RPC vs asynchronous messaging. Thanks man!
My pleasure!
1:51 Super comprehensive and spot on. Thank you.
If u found dis video helpful....the if is redundant here man your content is always helpful
Glad you think so!
This man deserves more subs! Thanks man, been watching all of your videos for a week now. I'm learning a lot. keep it up. greetings from the Philippines.
I appreciate that!
Love your work, your videos serve as a great reference and are always worth coming back to revise on a particular topic.
Many thanks! I appreciate the support!
Love your videos, fantastic breakdown - a massive help!
Glad you like them!
Hi Derek -- I recently came across your channel and have been binge watching your videos. They're great! Your straightforward, relaxed approach to clearly explaining various software architecture concepts is refreshing. Keep it up!
Thanks, from who I assume is a fellow Canadian.
@@CodeOpinion haha yep, definitely Canadian now living in the SF Bay Area
Thanks, this is very good comparison
This is a nice lesson. Thanks.
Glad you liked it!
Excellent video. Thanks for this one.
Glad you liked it!
I love this channel
Another great video! Thanks!
👍
Good info and to the point. Congratulations!
Wanted to make you a question though. In your example showing AWS VM's, you stop the active vm and in this particular case you can show the actual state of the vm. But how would you do this if you want to add a new client from the UI client to your database for example?. Yes, you said that you could notify the client saying "Hey! everything is ok" and create the message, send it to the broker and then trough signalr, push notifications or whatever notify the client. But, isn't this odd? When I add a customer in my accounting program (for example) I want to see the client right after I add it. How would you go for a case like this if you wanted to use async communication instead of synchronous? This leads me to think that it would be sensible to use messaging just for long running operations where the user really expects some delay between his action and the final result as in your AWS vm example.
Thanks in advanced.!
Yes, there are certain operations where a end user expects to see the result. In your example if you add a customer to your accounting program, that wouldn't be asynchronous. However, let's say you were uploading some receivables via a file into your accounting system. That likely could be asynchronous where the upload occurs and is put into blog storage. Then a message is enqueued with a reference to the blog storage ID/file where it then asynchronously processes the file.
You left out synchronous messaging :). There's a great book on this topic by one of the former Akka leads called "Reactive Design Patterns".
I also left out asynchronous request/response. I've done videos about Microsoft Orleans and Virtual Actors (cloud native objects) way back and plan to do more in the near future so stay tuned.
Hi nice video. The service that consume message from broker is a background job or what ? if after save data to db then produce message to broker failed, what should we do ?
Also, there is a known thing, that duplication of data is bad in any case. And MSA tends to duplicating required data for particular service. Could you please find some arguments which will help to convince others, that spreading data via events is good practice for MSA ?
I wouldn't call it good practice. It depends on the type of data and why it's being exchanged. ua-cam.com/video/anL-RGKz_Ak/v-deo.html
Again awesome and very useful topic!
Would you mind publishing a working project(end to end) for same example where command is being failed and passed too.
Ya I probably have something close in another sample project. Check out the one for eShopOnWeb related to this video: ua-cam.com/video/bxGkavGaEiM/v-deo.html
Could you please clarify, when you say send a message via broker, do you mean to send a query via broker to a queue and senders is waiting for a response message listening to another queue ? Is async\await for http request is not enough ? what for do you a queue in this case?
Check out this video, it might help clarify: ua-cam.com/video/tyCdEbDCNZE/v-deo.html
The real hard part for me, and I just can't find many people elaborating on that, is how to make services really independent.
e.g. I'm now breaking a monolith into 10-20 services. There are a lot of dependencies between domains. A lot of SQL JOINs that would instantly be translated into a synchronous HTTP/gRPC call to a secondary service (within the same user request).
Those can't be asynchronous, but splitting them also doesn't make sense.
Do I need a complete re-design?
I'd say re-align and start defining boundaries. One way to start is breaking off as small as you can, a piece that has minimal coupling to anything else.
This was very helpful thanks you just got a sub.
One question i have is so what happens when the placing of an order actually fails later and we already said order was placed. For example there is no quantity for the order ordered.
Depends on the business. The product may be back ordered in which a purchase order to the vendor is already placed. Maybe the customer is notified and an expected delivery date. If there is no future product to arrive via any PO, maybe the order is just refunded. This really isn't a technical concern it's more of a business concern.
Hi Derek. I just wanted to ask a quick question if you don't mind. I am currently working on an event-driven architecture project, where one of the services is a chat-service, based on CQRS pattern. My question is, for the initial state query, meaning loading the previous messages, would you suggest making it asynchronous or synchronous, based on your opinion/prior experience? Thank you for your time.
Seems like that initial call would be synchronous.
@@CodeOpinion Thanks a lot, I really appreciate your answer.
Hi Derek,
I recently started working at a new company, where the services communication is done with rabbitMQ RPC.
As far as I understand this is an async communication pattern via messaging queue, but it called RPC so does it fall under the RPC pattern?
I would really appreciate to get your opinion about rabbitMQ RPC in general :)
It's more about if the calling code is blocking. Meaning if the calling code sends a message to a queue, then is blocking waiting to pick up a response message in a different queue. And not until it gets a response (or times out) does it continue down the callstack. I'd avoid this where possible and handle replies asynchronously (non-blocking). If you haven't already check out this video I did on async request/response ua-cam.com/video/6UC6btG3wVI/v-deo.html
Hi sir, i encountered a project which I think is a distributed monolith app. They use Rest http to call one service to another. What is your opinion on that?
Check out this video where I talk about that: ua-cam.com/video/_4gyR6CBkUE/v-deo.html
@@CodeOpinion cool thank you.
Since you mentioned about pushing a notification to the client using Signal R,the first thing that came to my mind was the number of open connections we will have during peak traffic. If we have hundreds of thousands of users all connected using signal r, won't our service take a massive performance hit? Also then does it make sense to have an independent push notification service that can be independently autoscaled as per load?
Of course context matters. If you have that many active concurrent users, you might not want to. Or perhaps you use something like Azure SignalR Service to scale it and have dedicated separate processes to consume events from completed commands then push those to SignalR. It really depends on the context on how to implement it and what makes sense.
super
Damn didn't know matthew mcconaughey was so smart
👏
... or should you use async HTTP calls with a callback.
Without that option the whole video is meaningless.
"Async HTTP calls"... That doesn't make sense. HTTP Callbacks can be valid and that can be very complicated in user facing environments.
@@CodeOpinion The individual HTTP req. Is of course synchronous (just as enqueuing a message with one is), but when I say "async HTTP calls" I mean, making a req which immediately returns an waiting for the result in form of a callback.
Sure. I've covered using events and Websockets as callbacks in other videos.