Adopt wire to improve extensibility?
I stumbled upon psrpc and I find it really useful. I'd like to use it in some of my projects, but there are some downsides I'd like to address and they might be of interest for other people too:
There are multiple messaging technologies out there: NATS, RabbitMQ, Kafka etc. Each has its own set of pros and cons, especially regarding delivery guarantees, depending on the use case. Being able to swap the messaging backbone of psrpc from one project to another would be of great use and would help with adoption - e.g. you already use one of the messaging solutions in your infrastructure.
It seems that the above goal was somewhat addressed via the MessageBus interface which abstracts away the differences between Redis and NATS. Unfortunately, this approach will always limit the API of the MessageBus to the least feature rich technology involved - in this case probably Redis being the limiting factor.
Let's take NATS as an example. The request-response (1-to-1) pattern is already implemented at Core NATS level with random inbox subjects and response multiplexing as an optimisation. If you want to implement claims / affinity logic or even 1-to-M pattern, you can do it via scatter-gather.
Due to the MessageBus interface, the above features cannot be used and had to be (re)implemented at the psrpc library level. One might argue that you can live at the application level with the fact that Core NATS subjects are hardcoded inside psrpc together with the flow of exchanged messages.
But what if you want to make use of JetStream delivery guarantees / features for psrpc's Queue or Stream patterns? Then you have to (re)implement logic for this, both at the psrpc library level and at the application level.
I've taken NATS as an example because psrpc already provides an implementation over it, but the same arguments are also valid for RabbitMQ, Kafka etc.
My proposal, if you find the above scenario interesting and want to address it, is to:
- adopt wire for dependency injection
- group the
RequestSingle,RequestMulti,OpenStream,Join,JoinQueuefunctions into a client interface, let's call itClientTrigger - group the
RegisterHandler,RegisterStreamHandlerfunctions into a server interface, let's call itServerHandler
Use the current implementation as default wire providers for these interfaces. Let community developers come up with alternative implementations for different messaging backbones. One solution to use the alternative implementations at the application level would be to fork the psrpc library and just change the wiring file.
Please let me know if you are interested in this subject and if it's worth the time to make a PR with a proof-of-concept.
@adrian-branescu
Wire is a great tool, but it sounds like this could be better achieved by expanding MessageBus to inherit more of the logic from client Request/Open/Join functions and server Register functions. Then, you wouldn't need to fork the repo and change the wire file, just supply your MessageBus.
We are very open to PRs, but our focus is more on the LiveKit stack so we probably won't be making these changes in the near future unless we need to