You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We are currently experimenting with different architectures to figure out the best way forward to prepare for a multi process architecture in which having multiple processes doesn't feel fragile and cumbersome but rather robust, manageable and lightweight.
It currently seems that we are leaning towards an architecture that uses a single event bus to allow loose, decoupled, async communication between processes as explained in this comment.
There are a number of issues today that I believe are crucial to move this forward hence I'm collecting and throwing them out here.
Random ideas for the event bus
1. Get objective performance metrics
I believe the number one reason why we want this architecture is simplicity and robustness. However, we also need to take performance into account. There are several things that may make this approach less performant out of the box (though, with much much room for improvements) and it would be nice to measure and compare rather than just guess.
2. Allow routed events
To begin with, all events that are broadcasted are delivered to all endpoints of the event bus (where each endpoint is usually sitting in a different process). Then, inside these endpoints, the events are either processed because someone is listening to them via subscribe / stream APIs, or they are lost if no one is interested in them. Nevertheless, they are delivered to each endpoint no matter if they are actually consumed or not.
Groups of endpoints can be a powerful concept for when the exact ids/names of endpoints are unknown at design time but a statement about them belonging to a specific group can well be codified at development time (think: plugins!)
4. implicit routing via request API
While one of the primary use cases for the event bus is loosly coupled, async communication (think: PeerJoined / PeerLeft), there does exist a valid use case for communication pattern that fall more into the traditional request / response category. While one can do this with the existing APIs, the current event bus PoC does not have great support for this to make this more ergonomic and efficient.
It would be great to have an API roughly as follows.
request something and directly wait on the response in one API
ensure that the response is only delivered to this single callsite that was requesting it (implicit routing)
5. Allow all APIs to have timeouts
E.g.
result = await event_bus.request(PeerInfoRequest(), Config(timeout=1.5))
6. Make domestic events super efficient
Events that are scoped to only be broadcasted inside the endpoint that raises them do not need to go through the central coordinator at all and hence can be much much more efficient.
7. Check if we can move the event bus into it's own process and check if that would actually be beneficial
Currently, the event bus itself is sitting in the main process with endpoints being passed into other processes. That also means that all messaging is always going through this process. In other words an event raised in proc1, to be consumed in plugin-proc-n is always going through another hop proc1 -> main -> plugin-proc-n. That also means that there's a decent amount of processing going on in the process that hosts the event bus. But since the main process is at the very top of the hierarchy, it's kind of the natural / ideal place for this to happen. I believe our main process isn't performing much work anyway today but it would still be interesting to see if this work could move into another process.
8. Check if we can have an event bus without a central coordinator
More radical thought. Maybe we can achieve this kind of API even without going through a central coordinator hop
9. Check and compare to existing well established messaging solutions such as ZeroMQ
Something like zmq + aiozmq may actually provide better performance since the bulk of the work happens in native code. Yet it seems to have strong Python bindings. We might be even able to implement our event bus API on top of it or make the backend swappable.
The text was updated successfully, but these errors were encountered:
Inter-process communication in Trinity
We are currently experimenting with different architectures to figure out the best way forward to prepare for a multi process architecture in which having multiple processes doesn't feel fragile and cumbersome but rather robust, manageable and lightweight.
It currently seems that we are leaning towards an architecture that uses a single event bus to allow loose, decoupled, async communication between processes as explained in this comment.
That idea is currently in a PoC phase with a pre-mature event bus spike as well as two PoC PRs that demo it's usage (ethereum/py-evm#1202, ethereum/py-evm#1172).
There are a number of issues today that I believe are crucial to move this forward hence I'm collecting and throwing them out here.
Random ideas for the event bus
1. Get objective performance metrics
I believe the number one reason why we want this architecture is simplicity and robustness. However, we also need to take performance into account. There are several things that may make this approach less performant out of the box (though, with much much room for improvements) and it would be nice to measure and compare rather than just guess.
2. Allow routed events
To begin with, all events that are broadcasted are delivered to all endpoints of the event bus (where each endpoint is usually sitting in a different process). Then, inside these endpoints, the events are either processed because someone is listening to them via
subscribe
/stream
APIs, or they are lost if no one is interested in them. Nevertheless, they are delivered to each endpoint no matter if they are actually consumed or not.We can do better than that and allow events to be routed (related: routed events in Chromium multi process architecture).
Routing can happen implicitly (more on that later) or explicitly.
3. Explicit routing via
broadcast
APIThe
broadcast
API could accept an optional configuration object that could allow things like:Excluding specific endpoints for delivery
Only delivering to explicitly named endpoints
Excluding specific endpoints groups for delivery
Only delivering to explicitly named endpoint groups
Groups of endpoints can be a powerful concept for when the exact ids/names of endpoints are unknown at design time but a statement about them belonging to a specific group can well be codified at development time (think: plugins!)
4. implicit routing via
request
APIWhile one of the primary use cases for the event bus is loosly coupled, async communication (think:
PeerJoined
/PeerLeft
), there does exist a valid use case for communication pattern that fall more into the traditional request / response category. While one can do this with the existing APIs, the current event bus PoC does not have great support for this to make this more ergonomic and efficient.It would be great to have an API roughly as follows.
This API would allow to:
5. Allow all APIs to have timeouts
E.g.
6. Make domestic events super efficient
Events that are scoped to only be broadcasted inside the endpoint that raises them do not need to go through the central coordinator at all and hence can be much much more efficient.
7. Check if we can move the event bus into it's own process and check if that would actually be beneficial
Currently, the event bus itself is sitting in the main process with endpoints being passed into other processes. That also means that all messaging is always going through this process. In other words an event raised in
proc1
, to be consumed inplugin-proc-n
is always going through another hopproc1 -> main -> plugin-proc-n
. That also means that there's a decent amount of processing going on in the process that hosts the event bus. But since the main process is at the very top of the hierarchy, it's kind of the natural / ideal place for this to happen. I believe our main process isn't performing much work anyway today but it would still be interesting to see if this work could move into another process.8. Check if we can have an event bus without a central coordinator
More radical thought. Maybe we can achieve this kind of API even without going through a central coordinator hop
9. Check and compare to existing well established messaging solutions such as ZeroMQ
Something like
zmq
+aiozmq
may actually provide better performance since the bulk of the work happens in native code. Yet it seems to have strong Python bindings. We might be even able to implement our event bus API on top of it or make the backend swappable.The text was updated successfully, but these errors were encountered: