I'm designing a stand-alone, multi-threaded application in Java.
I'm trying to choose the best event-handling solution for his project.
I have 1-3 threads generating events (e.g comm thread completes file upload), while other threads might want to be registered for notification on this event.
I want the event-generating and event listening to be as uncoupled as possible.
What do you suggest?
Use an event bus.
An event bus can be thought of as a
replacement for the observer pattern,
where in the observer pattern, each
component is observing an observable
directly. In the event bus pattern,
each component simply subscribes to
the event bus and waits for its event
notification methods to be invoked
when interesting events have occurred.
In this way, an event bus can be
thought of like the observer pattern
with an extra layer of decoupling.
Here's a nice presentation about using an event bus ins GWT. It should give you a good idea about the benefits (and it's quite funny, too).
EDIT
The first link is mainly given as an example. It's really not that hard implementing something similar on your own which fits your needs.
I would use ExecutorServices to manage your thread pools. This way when you have a listener to an event, you can ensure the event is added to the right service either using a Proxy, or hande coded. e.g.
public void onEventOne(final Type parameter) {
executorService.submit(new Runnable() {
public void run() {
wrappedListener.onEventOne(parameter);
}
}
}
You can pass this listener wrapper as and be sure the event will be processed using the desired thread pool.
Using a Proxy allows you to avoid this type of boiler plate code. ;)
Do you really need a solution where each thread can register as a listener for each type of event? If so, use an event bus type solution (or a centralized observable with typed events).
If you don't need this flexibility a manager-worker setup could suffice, where the manager gets notified of events (like: "I'm finished with my job") and can fire up workers as needed.
Usage of an event bus is definitely the right choise. There are various solutions out there. You can also check out MBassador https://github.com/bennidi/mbassador.
It is annotation driven, very light-weight and uses weak references (thus easy to integrate in environments where objects lifecycle management is done by a framework like spring or guice or somethign). It provides an object filtering mechanism and synchronous or asynchronous dispatch/message handling. And it's very fast!
Google Guava has an event bus as well but it uses strong references which can be a pain if you do not have full control over your object lifecycle (e.g. spring environment)
EDIT: I created a performance and feature comparison for a selection of available event bus implementations including Guava, MBassador and some more. The results are quite interesting. Check it out here
http://codeblock.engio.net/?p=37
use command design pattern to decoupling
Related
I'm working on a web based application which uses java servlets for RPC calls.
I'm looking for a good way of dispatching and handling events on the server. In a PHP application I'm familiar with using Symfony's EventDispatcher class for adding event listeners and dispatching events, but I'm having a hard time finding something comparable in Java as most stuff I can find is about dealing with UI events and I'm wanting to both listen for and fire events on the server.
I'd also like the actual event handling to happen asynchronously on a separate thread or something so that, for example, an API call to handle adding a payment can do what's necessary, fire and event, and return immediately, even though the event might trigger some more time intensive stuff like sending emails or contacting a partner to inform them of the new balance.
Would I be best off just implementing this myself using my own event interfaces, ExecutorService/Runnable and Observer or Publish/Subscribe patterns? Or are there existing libraries (or built in features I don't know about) for doing some of this for me?
Thank you!
When using frameworks such as messaging queues (RabbitMQ, etc) or scheduling frameworks (Quartz, etc.), there is a need to implement some of the framework's interfaces (Job interface or MessageListener interface). It's a common practice to avoid putting any business logic inside the implementations, and delegate immediately to some other class. For example:
class MyJob implements org.quartz.Job {
private MyDelegate delegate = new MyDelegate();
#Override
public void execute(JobExecutionContext context) throws JobExecutionException {
String arg = context.getMergedJobDataMap().getString("arg");
delegate.run(arg);
}
}
From OO perspective, it makes sense because of the Single Responsibility principle. But other than that, it just leads to class bloat, and overly layered code.
Is there any practical benefit to delegation?
The good thing about principles is that there are so many of them.
In your case, I'd go for simple, direct implementations.
There's no need to extract business logic now; we can always do that later when needed.
A practical benefit of delegation is that you can reuse your business logic if you ever need to switch to a different framework / queue / interface / whatever, or if you need to add another one in addition to the current one (e.g. you're exposing your business method as a web service but want to add a REST API).
In many cases you should be spending little time as possible in callbacks. For example in Android, spending too much time in UI callbacks (run in UI thread) will block your application.
From Android documentation:
Specifically, if everything is happening in the UI thread, performing long operations such as network access or database queries will block the whole UI. When the thread is blocked, no events can be dispatched, including drawing events. From the user's perspective, the application appears to hang. Even worse, if the UI thread is blocked for more than a few seconds (about 5 seconds currently) the user is presented with the infamous "application not responding" (ANR) dialog.
I would like to #Subscribe a method in a Runnable that is created by a ScheduledFuture, so that I can signal it from another thread whether to run. Because a ScheduledFuture creates the object at some future time, there is no scope for the #Subscribe listener to pick up my event. So, I'm wondering how long an event sits in the bus, waiting to picked up by a listener? Is the actual pub-sub synchronous wrt sending/receiving events or will they sit in a queue for some duration before timing out?
Thanks.
Guava's EventBus does not provide sticky events. Additionally, due to the design of EventBus, it's not as straightforward as it could be to extend it to implement such a sticky design, as a lot of the internals are package-private (e.g. the logic to discover which methods on a registered object are annotated with Subscribe and mapping them to the proper event type).
I do think there are some other libraries out there which do provide this, like GreenRobot's event bus (https://github.com/greenrobot/EventBus), but without introducing a new library you'll have to build it more or less from scratch.
An alternative that I've used is RxJava's Observables with a replay(1) operator, so that subscribing to the observable will always immediately invoke the subscription callback with the last item, but it's not a drop-in replacement.
I have a J2EE application that receives and process messages (events). These messages contain various blocks of data. Different types of processing can be triggered depending of the type of data contained in a message.
I would like to have a simple internal event/message bus that can be used by the main processing thread to invoke different post-processors dependent on message content. For example, if a message is received of type A, I would like to be able to send an internal event to all post-processors that have subscribed to events of type A. The post-processors can then work their magic in their own time/thread. It would be nice (though not required) if the post-processors could be added/removed from the application via some sort of plugin-framework.
I understand that there are various message buses available. I am really seeking advice on an appropriate (lightweight) choice or perhaps a design pattern/example to cook my own.
Thanks in anticipation
Guava has and nice EventBus implementation. See the documentation.
You can also check out MBassador https://github.com/bennidi/mbassador.
It is annotation driven, very light-weight and uses weak references (thus easy to integrate in environments where objects lifecycle management is done by a framework like spring or guice or somethign). It provides an object filtering mechanism and synchronous or asynchronous dispatch/message handling. And it's very fast!
EDIT: I created a performance and feature comparison for a selection of available event bus implementations including Guava, MBassador and some more. The results are quite interesting. Check it out here
http://codeblock.engio.net/?p=37
I work on a web app that uses some Spring Application Event publishing and I was wondering what the advantages of it are? Why not just create a service call for everything that happens in the event handler's onApplicationEvent, and then call that service in place of publishing the event?
One of the advantages to using Spring's event publishing (observer pattern - http://en.wikipedia.org/wiki/Observer_pattern) is that the components are loosely coupled - there is no direct coupling between the publisher and the subscriber. Sure, they both have a dependency on the Spring Event API, but not on each other. This makes it possible to extend the application by adding/removing subscribers without affecting other subscribers (assuming that your subscribers don't depend on each other).
On the other hand, as you might have found, it can make debugging more tricky because it introduces a level of indirection between the source of an event and the overall outcome.
Yes, you can usually replace an event with a direct API call. Using Events are a good fit when:
you might in future need to take more than one independent action when the event occurs
the processing needs to be handed off to another thread to prevent blocking, e.g. sending an email (using a custom ApplicationEventMulticaster).
how the system handles the event, e.g. AuthorizationFailureEvent, does not depend on the outcome of the listeners.
You are writing a library, e.g. Spring Security, and direct API calls are not an option.
In answer to the part of the question that asks why not just create a service call; because someone else has already written the code, documented it and tested it.
Use Cases of Event-based Listener -
TDD becomes very handy(which in turn will eliminate bugs)
Best suited for Single Responsibility pattern (clean code) (Link for reference - https://www.youtube.com/watch?v=h8TWQM6fKNQ)