mxriverlynn / rabbus

A micro-service bus with built-in messaging patterns, for NodeJS and RabbitMQ
116 stars 26 forks source link

Architectural questions...just curious #29

Closed jnystrom closed 8 years ago

jnystrom commented 8 years ago
  1. You are dependent on Rabbot, why not hide that from the user of the library entirely? Why do I have to require Rabbot to use Rabbus, and then use Rabbot to connect to RabbitMQ?
  2. When I want to use a pub/sub, why do I have to create a class and inherit from Rabbus.Publisher instead of instantiating new Rabbus.Publisher(args)?

I am not judging, I am just interested.

mxriverlynn commented 8 years ago

great questions!

why rely on rabbot?

the tl;dr version: i was, historically, terrible at managing RabbitMQ connections and topology configuration. i needed a way to simplify it, add a few features that I didn't want to write myself, and provide a base library from which I could work.

the long version ...

the first version of Rabbus - years ago, before it was called Rabbus - only depended on amqplib directly. at the time, i didn't really know what I was doing with it, though.

my code to manage the connections and configuration sort of worked in my one specific scenario where the code was originally written. over time, though, i realized how poorly i was managing things.

i had too many connections open. i wasn't using enough channels. I was leaking callback functions left and right, causing all kinds of problems.

it was a mess.

so i looked for a better way to manage the messaging patterns i wanted to use. i replaced amqplib with various other libraries that created better abstractions on top of it.

each of the libraries i tried provided some benefit while also creating some additional problems as my knowledge continued to grow. there was too much magic in the code and i couldn't get at the rabbitmq features i wanted.

wascally - which became rabbot - solved these problems for me, with a set of opinions and implementation details that mostly matched the way i think about RabbitMQ.

i was able to more easily build my own messaging pattern implementations on top of wascally, because i no longer had to worry about managing the connection or topology implementation (separate from topology design).

...

in the future, i probably want to remove the rabbot dependency. i like the way it works, for the most part, but there are parts of it that i don't like. it provides a lot of features, though, and there would be some effort in determining which features need to be replicated or removed if i took it out.

inheriting from Rabbus.Publisher vs new Rabbus.Publisher

This is mostly a style preference for me, coming from a background of OO code and testing in other languages.

I'm a fair advocate of test automation (though i don't do as much as I would like, honestly) and part of that is the philosophy that i don't test APIs that I don't own.

even if i, Derick Bailey, own the Rabbus code, the project using it does not. my "scheduler" system for my client uses Rabbus and needs to test the API calls to send and receive messages, without actually sending and receiving them. i don't want to involve Rabbus directly, so I inherit from Rabbus to create objects that my code in that project owns - specific APIs for the specific needs of the app.

i'm growing less fond of inheritance in JavaScript every day, but i haven't found a better way to compose the producers and consumers, yet (mostly due to lack of time to explore ideas and options).

...

realistically, you don't have to inherit from the Rabbus producer or consumer objects. you could use them directly.

and if you're creating an app-specific API for your code to use, hiding the Rabbus objects as an implementation detail is probably a better choice.


hope that helps! let me know if you have other questions :) i'll close this issue, but feel free to continue the discussion here or open new issues if you prefer that.