Hot questions for Using EventBus in architecture

Question:

Are there any Event Driven Architecture jQuery plugins?

Step 1: Subscribing

The subscribers subscribe to the event handler in the middle, and pass in a callback method, as well as the name of the event they are listening for...

i.e. The two green subscribers will be listening for p0 events. And the blue subscriber will be listening for p1 events.


Step 2: The p0 event is fired by another component to the Event Handler

  1. A p0 event is fired to the Event Handler
  2. The event handler notifies it's subscribers of the event, calling the callback methods they specified when they subscribed in Step 1: Subscribing.

Note that the blue subscriber is not notified because it was not listening for p0 events.


Step 3: The p1 event is fired a component to the Event Handler

The p1 event is fired by another component

Just as before except that now the blue subscriber receives the event through its callback and the other two green subscribers do not receive the event.

Images by leeand00, on Flickr

I can't seem to find one, but my guess is that they just call it something else in Javascript/jquery

Also is there a name for this pattern? Because it isn't just a basic publisher/subscriber, it has to be called something else I would think.


Answer:

You probably don't need a plugin to do this. First of all, the DOM itself is entirely event driven. You can use event delegation to listen to all events on the root node (a technique that jQuery live uses). To handle custom events as well that may not be DOM related, you can use a plain old JavaScript object to do the job. I wrote a blog post about creating a central event dispatcher in MooTools with just one line of code.

var EventBus = new Class({Implements: Events});

It's just as easy to do in jQuery too. Use a regular JavaScript object that acts as a central broker for all events. Any client object can publish and subscribe to events on this object. See this related question.

var EventManager = {
    subscribe: function(event, fn) {
        $(this).bind(event, fn);
    },
    unsubscribe: function(event, fn) {
        $(this).unbind(event, fn);
    },
    publish: function(event) {
        $(this).trigger(event);
    }
};

// Your code can publish and subscribe to events as:
EventManager.subscribe("tabClicked", function() {
    // do something
});

EventManager.publish("tabClicked");

EventManager.unsubscribe("tabClicked");

Or if you don't care about exposing jQuery, then simply use an empty object and call bind and trigger directly on the jQuery wrapped object.

var EventManager = {};

$(EventManager).bind("tabClicked", function() {
    // do something
});

$(EventManager).trigger("tabClicked");

$(EventManager).unbind("tabClicked");

The wrappers are simply there to hide the underlying jQuery library so you can replace the implementation later on, if need be.

This is basically the Publish/Subscribe or the Observer pattern, and some good examples would be Cocoa's NSNotificationCenter class, EventBus pattern popularized by Ray Ryan in the GWT community, and several others.

Question:

I am using vertx3

I need to use redis in order to set and get values.(Redis might be changed to something else in the future)

Iam looking for best practice design for my implementation.

I am working on vertx cluster and I need to retrieve a messages via the eventbus extract the message and insert into Redis.

In the other hand I can get requests via web and also extract the messages and insert them into redis

Two options:

  1. Should I have a "redis-verticle" that get the messages via the bus and write them.

  2. Should I create a "Listener verticle" that will hold DAO which will hold RedisRepo object which will write them.

    I will also be able to handle the web calls and hold this DAO object

If I was on spring-app I would create a DAO which holds RedisRepo and Inject it into my service layer but here we got the eventbus so I am not sure.

(btw the redis datasource me be changed to something else so I gotta think about generic wrappers)

1. 

public class RedisRepoVerticle extends AbstractVerticle {

...
 public void start() {
 client = new RedisClient("localhost", 6379);
                 connection = client.connect();
...

vertx.eventBus().consumer("redis-operation", (handler) -> {
            {
                JsonObject msg = new JsonObject(handler.body().toString());
               //write straight to Redis 

            }
        });

}






2. 

     public class RedisMessageListener extends AbstractVerticle {
        DatasourceDAO datasource
        ...
         public void start() {
         client = new RedisClient("localhost", 6379);
                         connection = client.connect();
    ...

    vertx.eventBus().consumer("redis-operation", (handler) -> {
                {
                    JsonObject msg = new JsonObject(handler.body().toString());
                   datasourceDAO.writeToRedis(..); 

                }
            });

    }

//datasourceDAO will hold RedisRepo object

If I take the second option should I start maintain singletons? I dont want to duplicate my daos which will duplicate my redisrepo's classes


Answer:

I think it would be better to implement the second case, create a seperate verticle that will hold a redis client and a seperate verticle that will accept, process and pass the requests to the redis. Each verticle should have separate connection pool, and you might get in problems with maintaining multiple connection pools in the future when creating separate connections from each verticle to the redis.

The DAO-s replication should be not a case here. I would suggest you taking a look at https://github.com/vert-x3/vertx-service-proxy. It's a vert.x sub-project which can help you understand what a verticle itself is. You should tread a verticle as a service (or in particular, DAO) that provides a set of methods. It behaves like a singleton, that is you don't create new instances of a verticle on-demand, but there can be more than one instance of it depending on the configuration (http://vertx.io/docs/vertx-core/groovy/#_specifying_number_of_verticle_instances).