Understanding how netty works - asynchronous

I'm trying to understand how netty works, and after reading some of the documentation I was to see if I understood how things work at a high level.
Basically netty has an event cycle, so whenever you make a call it gets serialized and the request gets pushed down to the o/s level, and it uses epoll and waits for an event to send back to netty.
When the operation system generates an event that netty subscribed to, netty then has an event loop that gets triggered.
Now the interested part here is, the event that gets triggered has to be parsed, and the client code (or custom code) has to figure out who actually this event is for.
So for example, if this was for a chat application, when a message is sent, it is up to the client code to figure out to send this message via ajax to the correct user.
Is this, at a high level, a correct overview of how netty works?
BTW, when netty listens for events sent via epoll, is this event loop single threaded or does it work from a pool of threads?

Sounds correct to me.
There are more than one event loop thread in Netty, but it does not mean a single Channel's event is handled by multiple event loop threads. Netty picks one thread and assigns it to a Channel. Once assigned, all events related with the Channel is handled by the picked thread.
It does not also necessarily mean that an event loop thread handles only one Channel. An event loop thread can handle multiple Channels.

Related

DB Transaction and Integrations Events dispatch - how to make it atomic?

I'm designing a system with multiple bounded contexts (microservices). I will have 2 kind of events.
Domain Events, which happens "in memory" within single transaction (sync)
Integration Events, which are used between bounded contexts (async)
My problem is, how to make sure that once transaction is committed (at this point I'm sure all Domain Events were processed successfully) that Integration Events are successful as well.
When my Transaction is committed, normally I will dispatch Integration Events (e.g. to the queue), but there is possibility that this queue is down as well, so previously just-committed transaction has to be "reverted". How?
The only solution that comes to my mind is to store Integration Events to the same DB, within the same Transaction, and then process the Integration Events records and push them to the queue - this would be something like "using current DB, as a pre-queue, before pushing it to The Real Queue (however I read that using DB for this is an anti-pattern).
Is there any pattern (reliable approach) to make sure both: Transaction commit and Message pushed to the queue is an atomic operation?
EDIT
After reading https://devblogs.microsoft.com/cesardelatorre/domain-events-vs-integration-events-in-domain-driven-design-and-microservices-architectures/ , the author actually suggests the approach of "pre-queue" in same DB (he calls it “ready to publish the event”).
Checkout transactional outbox pattern.
This pattern does create a pre-queue. But the nice part is that pushing messages from pre-queue to real queue is fully decoupled. Instead you have a middleman called, a message relay that reads your transaction logs and pushes your event from to the real queue. Now since sending message and your domain events are fully decoupled, you can do all your domain events in a single transaction.
And make sure you that all your services are idempontent(same result despite duplicate calls). This transactional outbox patter does guarantee that messages are published, but in case when the message relay fails just after publishing(before acknowledging) it would publish the same event again.
Idempotent services is also necessary in other scenarios. As the event bus(the real queue) could have the same issue. Event bus propagates events, services acknowledge, then network error, then since the event bus is not acknowledged, the same event would be sent again.
Hmm actually idempotence alone could solve the whole issue. After the domain events computation completes(single transaction), if publishing message fails the service can simply throw an error without roll back. Since the event is not acknowledged the event bus will send the same event again. Now since the service is idempotent, the same database transaction will not happen twice, it will basically overwrite or better(should) skip and directly move to message publishing and acknowledging.

notify controller action method from other independent handler within specific time

I have a situation where I need to wait for response from device(using mqtt broker which doesnt matter in current questions context).
Whenever I get an API call on one specific endpoint
I need to wait(2-5 seconds depending upon the need) for response from device on the other handler(mqtt handler => https://github.com/gausby/tortoise)
this handler needs to notify me somehow I got this msg(if handler received msg withing that time) for the particular device id
if device matches and controller action method get notified we send back success response otherwise we send failure response
Any msg received before or after wait time doesnt matter(just consider it unsubscribed)
I am not really sure about whats the best way to achieve above requirement. any help is welcome, thanks
spawn() a process for the first handler. In the first handler, spawn() another process for the second handler passing self() as one of the arguments. Then enter a receive clause with a 2-5 second timeout specified in the after clause. Have the second handler send() a message to the first handler with the data that the second handler acquires.
If the receive in the first handler times out, then do whatever you want to do in the after clause, if the receive reads a message before it times out, then do whatever you need to do with the data.
Then, if you let the process running the first handler die, then you won't have to worry about junk messages in its mailbox.

Apache Camel Architecture

I am working on prototyping a new web service for my company and we are considering Apache Camel as our integration framework. Here is a quick run-down of the high-level architecture:
-IBM Websphere MQ as the queuing solution
1) we receive http request
2) asynchronously persist this request
3a) do some processing on the request
3b) send to another tier for further processing
4) asynchronously update the request record in DB
5) respond to caller
What I want to do is:
When a http request comes in, put it on a queue to be processed and wait n seconds. If the web handler doesn't get a response in n seconds, reply to the caller with a custom message
Once the request is on the processing queue, a camel route is listening to this queue to process. When it pulls a message from queue, put a copy of the request on a different queue to be persisted asynchronously. Do some processing on the request. Then send it to another queue to be further processed and wait for a response. Then put it back on the persist queue to be asynchronously updated.
Then respond to web listener. Then web listener responds to web caller.
I am reading everything I can about Apache Camel and there is a lot of information about there. I might be on a little bit of information overload, and any help on the following concerns would be greatly appreciated:
1)
If the web listeners use an InOut exchange (with the first processing tier) without a replyTo queue defined, it will create a temporary queue for the response. What happens if this request times out? I understand I can set a requestTimeout on the exchange and, if it times out, catch that exception and set a custom message. But, will that temporary queue be killed? Or will they build up over time as requests time out?
2)
When it comes to scaling the processing tiers (adding more instances of those same routes on different machines), is it customary that if the instance that picks up the response (using a fixed reply to queue) is different than the instance that picked up the request, all the information about the original request is inside the message, so there is no need to share data across instances (unless of course there is data that is shared, like aggregrates and such)?
Any other tips and tricks when building a system like this would be very helpful.
Thanks!
I would say this solution is too complicated and there are too many areas which are hard both in terms of maintenance and also complexity. There is too much many steps mixing async and sync communication.
Why not simply the solution to the following steps:
Synchronously http request
Put message on MQ with reply to header
Message is picked up and sent to backend
If reply is not received within a given time transaction is terminated.
The reply to queue is removed
Requestor is notified.

Signalr server side, OnDisconnect only called for 1 hub

I am writing a web application an it uses SignalR. On the server c#, I have two hubs.
It really does need to be two otherwise I would just merge them and solve the problem.
The problem that I am having, is that while I am aware that SignalR client side, hubs
will share a connection. The issue I am having, is that when I close the browser, or call stop on the client. Only 1 of my server side OnDisconnect(bool stopCalled) events will fire.
I somehow expected that both would fire when the client disconnects.
Am I being silly or doing something wrong perhaps?
Any info will be greatly appreciated.
Louis
I think the problem you are experiencing might be due to you not hooking up any event handlers (i.e. client hub methods) to the Hub that isn't triggering OnDisconnected. If this really is the cause, OnConnected also shouldn't be triggered on the same Hub.
The SignalR Hubs API Guide for the JavaScript client goes into some detail in one of its "notes" about why this is the case. Here's the relevant quote:
Note: Normally you register event handlers before calling the start method to establish the connection. If you want to register some event handlers after establishing the connection, you can do that, but you must register at least one of your event handler(s) before calling the start method. One reason for this is that there can be many Hubs in an application, but you wouldn't want to trigger the OnConnected event on every Hub if you are only going to use to one of them. When the connection is established, the presence of a client method on a Hub's proxy is what tells SignalR to trigger the OnConnected event. If you don't register any event handlers before calling the start method, you will be able to invoke methods on the Hub, but the Hub's OnConnected method won't be called and no client methods will be invoked from the server.
Every reference to the OnConnected method applies equally to the OnDisconnected method.
You can add an arbitrary event handler to your Hub before calling start() on the client to ensure that OnConnected and OnDisconnected get called on that Hub. It doesn't matter if the event handler will never be called. Ex:
$.connection.myHub.client.thisWillNeverBeCalled = function () { };
$.connection.hub.start()//...
As long as the first line is there, OnConnected and OnDisconnected should be called on MyHub.
In the end, after almost 2 days troubles shooting and browsing the web for answers.
I ended up just merging the two hubs into a single hub. It might not be the most elegant solution, but it did get the job done and progress can now be made on the rest of the app.
Thanks for the advice though from everyone :)
Louis

QObject based class has a queued connection to itself

I was digging into some source code I am working on. I found a peculiar statement that someone had coded. The source code is a GUI application with a QML GUI and uses QT 4.7.x.
The snippet below belongs to core application logic.
// connect signal-slots for decoupling
QObject::connect (this, SIGNAL(setCurrentTaskSignal(int)), this,
SLOT(SetCurrentTaskSlot(int)), Qt::QueuedConnection);
It's strange that the object connects to itself via a queued connection which essentially means that the object may "live" in different threads at the same time?
At first glance It didn't made any sense to me. Can anyone think of any reason why such a connection would be plausible or needed?. Would this even work?
It will work without any problem. Maybe there was some event loop processing required before calling SetCurrentTaskSlot?
Note that QueuedConnection doesn't mean that something is in different thread. QueuedConnection means only that when signal is emitted, corresponding slot won't be called directly. It will be queued on event loop, and will be processed when control will be given back to event loop
The queued connection implies nothing about where the receiver lives. The opposite is true: to safely send signals to an object living in another thread, you must use queued connections. But you can use them for an object living in any thread!
One uses a queued connection to ensure that the signal will be delivered from within the event loop, and not immediately from the emit site as happens with direct connection. Direct connection is conceptually a set of calls to function pointers on a list. Queued connection is conceptually an event sent to a clever receiver who can execute a function call based on the contents of the event.
The event is the internal QMetaCallEvent, and it is QObject::event that acts upon this event and executes the call.

Resources