kontraktor icon indicating copy to clipboard operation
kontraktor copied to clipboard

Question: How to model Message/Event Bus API

Open agentgt opened this issue 8 years ago • 2 comments

Our system uses an in house message bus (the best comparison would be probably be to Vert.x EventBus).

public interface MessageBus {
   //Pub/Sub
   void publish(Object o);
   //Request/Reply the request interface is just for semi typesafety
   <T> Observable<T> call(Request<T> o);
}

Basically the concrete type of the Object o is used to determine routing/delivery. We have services (ie singleton like) in our system that then have annotated methods like:

@Subscribe
public void onMy(MyMessage vm) { }

@Respond
public MyResponse handle(MyRequest r) { }

// or

@Respond
public Observable<MyResponse> handle(MyRequest r) { }

Now you might deplore this model but it has held up well for my company and existed prior to all the actor frameworks. Basically our internal APIs are composed of message object types and not methods or URL and HTTP method type in terms of REST. The message type is the contract.

I would like to try Kontraktor since it has some nice serialization optimizations for the async portions of our system. My idea is to create an actor that is basically the message bus and takes plain Objects but I realize this will probably break serialization and/or hurt performance since the actor is basically taking all objects of any type. I also would imagine kontraktor has its own routing that needs type information and it might not be able to vary?

What would you recommend in following an MessageBus/EventBus pattern?

agentgt avatar Sep 27 '15 16:09 agentgt

(I'll reply in detail tomorrow, no time now)

  1. if your platform only allows for TCP (so the sender actually replicates a message to N receivers) it should be straight forward to do this. Any actor has generic methods "tell" and "ask", which can be used to throw in arbitrary message objects, ofc you can also define your custom receive methods. I'll provide a small sample tomorrow. Downside is, that for each receiver a separate message ineeds to be sent over the network. So for high rates with many receivers this does not work well. So 10k msg/second with 10 receivers = 100k msg per second sent.
  2. for ultimate performance you might want to use native multicast networking (e.g. fast-cast, aeron). However this won't work in the cloud and in most enterprise network environments (security ..). My fast-cast lib is for native multicast with a send(Object) interface. With native multicast, the sender sends a message once and the network hardware replicates the message to all receivers. One can achieve very high message rates with this setup. Downside is network configuration effort, since native mutlicast is unreliable, a custom reliability implementation is needed. fast-cast implements reliable mutlicast (no packet loss, ordered delivery).

2015-09-27 18:47 GMT+02:00 Adam Gent [email protected]:

Our system uses an in house message bus (the best comparison would be probably be to Vert.x EventBus).

public interface MessageBus { //Pub/Sub void publish(Object o); //Request/Reply the request interface is just for semi typesafety <T> Observable<T> call(Request<T> o); }

Basically the concrete type of the Object o is used to determine routing/delivery. We have services (ie singleton like) in our system that then have annotated methods like:

@Subscribepublic void onMy(MyMessage vm) { }

@Respondpublic MyResponse handle(MyRequest r) { } // or

@Respondpublic Observable<MyResponse> handle(MyRequest r) { }

Now you might deplore this model but it has held up well for my company and existed prior to all the actor frameworks. Basically our internal APIs are composed of message object types and not methods or URL and HTTP method type in terms of REST. The message type is the contract.

I would like to try Kontraktor since has some nice serialization optimizations for async portions of our system. My idea is to create an actor that is basically the message bus and takes plain objects but I realize this will probably break serialization and/or hurt performance since the actor is basically taking all objects in and I would imagine kontraktor has its own routing that needs type information.

What would you recommend in following an MessageBus/EventBus pattern?

— Reply to this email directly or view it on GitHub https://github.com/RuedigerMoeller/kontraktor/issues/16.

RuedigerMoeller avatar Sep 27 '15 19:09 RuedigerMoeller

you can checkout / view the example project here: https://github.com/RuedigerMoeller/kontraktor/tree/trunk/examples/pub-sub/tcp-based/src/main/java/pubsub/point2point

  • websockets based pub-sub (requires mediator service ["gossip server"]). Could also switch to TCP easily
  • supports topics
  • supports fire-and-forget broacasts ("tell")
  • supports one-to-many requests obtaining a result from each member subscribed to the topic

all done in a few lines of code :)

let me know if this addresses your needs

RuedigerMoeller avatar Sep 28 '15 17:09 RuedigerMoeller