#Intro
This is a Java event library , to promote event driven programming.
The purpose of this framework is to provide an easy way to generate and process events.
It is encouraged to use only events as a way of communication between in app processes and third party systems.
These, through their format, can be logged, acted upon, analyzed, distributed and so on..
Events should be used to transmit information in real time from important parts of the application.
Then, any party concerned can register one or more generic or specialized listeners to further process those events.
#Why
We live in the age of big data, when we want to collect events about everything, to better understand certain aspects of the system, even how the system itself is running :
Events are structured, actionable, storable, distributable, generally more *able then logs
If you spend some time capturing information in a relevant point of the application, make sure you’re doing it in the most generic and useful way possible
You can more easily generate logs from events than the other way around
The system gets to be more decoupled when using an event driven approach
More flexibility and control without altering the existing code ( just add more listeners on your events, or tweak the configuration file )
Be prepared for scaling ( an event driven architecture is easier to scale )
In many cases it makes testing much more easier - make sure you fire the right events in the right places, and then simply listen for the expected events, and then just fire a TEST:PASSED event if you like :)
#How does an event needs to look like ?
Well, let’s look at some desirable characteristics:
##What kind of information do we want to transmit ?
scope
, category
, name
##Who would be interested in a certain event ?
##How would we control logging of an event ?
This actually leads to another, more broader question, namely what parties do we want to control what information ?
Well, the main event information can only be controlled by the developer, from the code. Only there this kind of info is available and can be added to the event. So this cannot be debated.
However, the meta information, which specifies how an event should be treated and further processed through the system, or if an event should be fired at all, can and should be configurable from outside the code ( e.g. from a configuration file ).
I also see the usefulness of a sysadmin being able to request for a particular event more informations about the state of the system when this event was generated. The way in which this could be done should be further discussed, however I see two possible approaches: either adding more info to the original event, or generate another event with additional data that can be directly linked with the original one.
So the extra feature here would be the ability to gather more info for and event
What events are allowed to be posted to the bus. Only if an event is allowed for posting, the developer should bother to fully build the event
Logging level
Gather more runtime info for a particular event
Listeners and their configuration
The whole bus configuration
So by now, it’s clear that we need an external, static configuration, that offers a certain level of control. The limitation is that it’s static, and will remain the same for the whole operation of the application.
We may want a dynamic mechanism as well, through which some components can alter the way in which an event is processed during runtime.
In order to allow for this feature, we may structure an event like this :
The header may consist of :
How would we control logging of an event ?
With the above structure at hand, we can do this :
##Custom events
One can also create custom events by extending Event class and using EventType annotation:
public class SimpleEvent extends AbstractEvent< String > {
// todo your code
}
#Processing events
Now that we can trigger events, we may want to use them to implement a certain business logic.
We can implement a certain behavior through a set of event listeners.
To further encapsulate this, we can create an event node with its own internal bus and its own listeners that acts as an independent agent.
So an event node will be able to :
This provides a robust model for event processing and event distribution.
Events, through their nature, are concurrent. The event bus processes the event in the thread that does the posting.
This requires for our event node to be thread safe. We can achieve this in two ways:
By far, the latter one seems the most sane and fortunately the most efficient.
Why is that ?
Basically you would want to expedite the processing of an event as fast as possible. By processing one event at a time, this is ensured, because you won’t loose time with synchronizing threads or, sharing cpu resources between more events.
So, now it’s settled that we have one processing thread per node.
But what if we will have 1000 event nodes running in our jvm instance. Will we have 1000 threads running ? This would be overkill.
What is the solution ?
The obvious solution is to make all these nodes share a pool of execution threads. But this still wouldn’t be quite efficient.
Better yet, we can make all of them share just one thread. This way we can ensure that all the resources go into executing events and not in something else.
But this is dangerous. What if the handling of an event takes really long. Won’t this block everything ?
Well yes. But there’s a simple solution to this. Just make that node run in its own thread.
So there you have it. All the lightweight nodes will share a single processing thread, and the ones doing heavy lifting can spawn their own thread. However this should be used judiciously. There’s no way you could achieve performance if you have lots of threads messing around.
#Distributing events
* Distribute events between any number of bus instances organized as nodes
* The distribution has to work regardless of the medium separating the instances (same machine, same network, the internet )
* Transmission and reception of events has to be controlled by security rules
* The network should be decentralized
###Security: - what kind of events should be forwarded to a peer - should a peer be accepted at all
##Routing events between two unconnected nodes
So we have two nodes that don’t have direct access to each other, but they have a communication route through a number of peer nodes.
###How do we let at least one node to get events from the other, without doing a full broadcast ?
The easiest solution is for each node to keep a routing table to each remote node, with the direct peers that can be used to reach that node. This information can be extracted from the broadcast events that reach a node. The last relay node for an event can be used as a via for the source node.
First, a node should be aware of the existence of a remote peer in order to register to it. Alternatively, another node can do the registering on its behalf.
Then the initiating node will send a peer:request:register event to the remote node ( this will have to be broadcasted to all / alternatively maybe each node will have to keep routing tables )
The receiving node will register the remote node and make an entry in its routing table for that node ( if it doesn’t have one) , with the last relay node as a via. Then it will send a peer:respose:registered event.
Then all the events that should get to the remote peer, will be routed to one of the via nodes for that peer
Each node when receiving an event will check if this should be further forwarded to reach the desired receiver.
If this is one of its direct peers then it will simply send it, otherwise it will check if it has a via for this node in its routing table and send it through the found via ( if any ).