Traffic lights for the event bus

Wow! This is warming up. Thanks all for your comments, emails, and for taking the bus with me!

There're lots of interesting things in your comments so I'll try to review them all, as time permits, and express what I think. So please correct me if I'm wrong. Get ready for one of the biggest blog entries in the Internet! (Sorry by that :-()

Event Buses and Event Queues

As Kevin points out there're similarities between event buses and the AWT Event Queue. After all, let's be honest, both are ways to deliver events to listeners!

In fact I think that taking control of the event queue may be of great help in GUI development. It allows you to be asynchronous. It allows you to take control on event delivery. I've taken a look at foxtrot (as you know foxtrot is a well known framework for handling asynchronous operations in Swing) and found that... they're taking control of the event queue too!! See:

In contrast, Foxtrot lets the Event Dispatch Thread enter but not return from the listener method, instead rerouting the Event Dispatch Thread to continue dequeuing events from the Event Queue and processing them. Once the worker thread has finished, the Event Dispatch Thread is rerouted again, returning from the listener method.
But, wait, there're many more examples out there! As Jonny (thanks, Jonny, I didn't know about it!) kindly pointed out we have the Event-Listener Framework (ELF), too.

So it seems taking control of the event queue is key to ease things. Taking control of the event queue seems a powerful idiom. Now, what is the difference between an event bus and a controlled event queue? Don't they both deliver events?

Well, as far as I understand, the main difference may be explained with this drawing...


   +---------------+ +----------------+ +-------------+ +-------------+
   |               | |                | |             | |             |
   | ActionManager | | EventResponder | |  AntModule  | |  AntModule  |
   |               | |                | |(ProjectNav) | |(SourceEdit) |
   +---------------+ +----------------+ +-------------+ +-------------+
           |                  \^               \^               \^
           |                  |               |               |
      ActionEvent         EventObject      AntEvent       AntEvent
           |                  |               |               |
           v                  v               v               v
  /---------------------------------------------------------------------\\
 /                                                                       \\
<                                   EventBus                              >
 \\                                                                       /
  \\---------------------------------------------------------------------/
           |                  \^               \^               \^
           |                  |               |               |
      EventObject         ChangeEvent      BuildEvent     EventObject
           |                  |               |               |
           v                  |               |               v
   +---------------+ +----------------+ +-------------+ +--------------+
   |               | |                | |             | |              |
   |   Console     | |  ProjectProxy  | |    Ant      | | (Your Module)|
   |               | |                | |             | |              |
   +---------------+ +----------------+ +-------------+ +--------------+

... that I've copied (without permission!! ;-)) from the antidote design document (antidote is a GUI for Apache's ant).

This is, I think that the event bus delivers events the same way an event queue does, but it's the single point of contact between components. Or, as the Antidote design document nicely explains:

"In order to keep the coupling among application modules to a minimum, a single point of reference is needed for coordination and data sharing."
(Note that this is exactly what ELF does, too).

Topics, Channels and ... interrupt levels!

Note as well that the Antidote design document describes different topics (or channels) to deliver events. They call them "interrupt levels".

If you read carefully you'll see a VETOING topic, a MONITORING topic, and a RESPONDING interrupt level. Now, don't these look similar to the ones Tim has been suggesting since the very first day? Add to these interrupt levels a "COMMAND" topic (where the Open/Save/Close events are delivered) and a "STATE" topic (where the Opened/Saved/Closed events are delivered) and you're (I think) pretty much solving Tim's concerns (Am I right here, Tim?)

Note, though, that Antidote seems to deliver events (interrupt levels) to all bus components. Whether they're interested in listening or not. We may refine this a little bit to avoid bothering components with events they're not intersted in.

Traffic lights for bus lines

And here we come to the tough part. Decide how to coordinate that event traffic. Decide which events go in which bus lines. Define how many topics. Place some traffic lights somewhere.

After all, as Ronan Bradley (CEO, PolarLake) clearly stated, the ESB is just a communication mechanism. The mediation, the orchestration, is the tough part.

So I can think of different mechanisms and I would like your feedback on this.

I. Event aggregators as event sinks

The very first approach is having one or more listeners of the bus holding instances of other components. These aggregators will receive different events from different components in the bus. And will then orchestrate them, making direct method calls on those components. Note that these are listen-only aggregators.

  • One of these aggregators (status bar aggregator) would listen the bus for the "FileSelected" and "FileOpen" events and then invoke the "statusBar.setMessage(...)" on the status bar.

  • Another of these aggregators (editor aggregator, say) would listen the bus for the "FileOpen" event (coming from either the menu bar or the filesystem viewer) and then invoke the "editor.open(...)" method of the editor.

Building such aggregators is simple. All macro-components have a single listener: the event bus. And the event bus, in turn, has one or more listeners: the aggregators.

Furthermore, aggregators can talk themselves through the bus. So they're event sinks, but may produce (simulating) events from the components to fire action in another aggregator. For instance, an aggregator could post a "FileOpen" event in the bus, so the "editor aggregator" workflow above will be executed.

This approach is modular too. You can add different aggregators. Adding new features to the GUI requires new aggregators. All control logic is in the aggregators, that manipulate the data model and deliver pieces to components. Components are just pasive views between the user and the controller.

In this approach macro-components are loosely coupled. You don't mix listeners between components. You don't have the status bar listening the filesystem viewer, nor the editor listening the menu bar. One-to-one listeners are gone. Instead all components have a single listener: the event bus.

With this approach there's no need to deliver command events to components, either, because aggregators invoke methods on them directly. So there's no need to veto events. No command events. No need to worry about locking problems: the order of reactions to events is fully controlled, in Java, in the aggregators.

I think this approach architects all this event handling in three layers. See:

  • A view layer, with macro-components, responsible for visual display of data and primary user event handling.
  • A bus layer, responsible for routing events from components to aggregators. Events may be delivered either synchronously or asynchronously.
  • An aggregator (controller) layer, responsible for handling events from components, coordinating them and manipulating the data model.
Maybe a small diagram clarifies things a little bit?

Type I aggregators

II. Event aggregators as event producers

The second approach I can think of is similar to the previous one. "Type II" aggregators will listen the bus for component events, too. But will \*not\* have any instances pointing to the components. Instead of making direct method calls these aggregators would just send events, command events, to components.

  • The "status bar aggregator" could receive the "FileSelected" and "FileOpen" events from the bus and then send a "setMessage" event through the "statusbar" "command" channel.
  • And another of these aggregators, the "editor aggregator", could receive the "FileOpen" coming from the menu bar of the filesystem viewer and then send an "open" command event through the "editor" "command" channel.

This approach seems to be very powerful (does it not, Tim? ;-)).

Since there's not a direct link between macro-components, these may be replaced (by mock macro-components in order to do some gradual functional tests) or may even be absent (and command events would then be simply ignored).

You could even run the whole aggregators with a bus... without a GUI!. Replace all macro-components with mock objects (responsible for receiving and sending events) and you could exercise the whole controller logic.

You could even substitute the presentation logic and reuse the controller logic. So you could have a view layer with SWT and another view layer with Swing, and swap between them both without touching a single line of the controller logic.

Note also that I say "statusbar" "command" channel and "editor" "command" channel, so I suggest having different "command" channels for different components, and not just a single "command" channel to all components. By doing so I think we get rid of vetoing and the lock problems Tim points out (am I right here)?

So, to summarize, these "Type II" aggregators would just replace direct method calls (and instances) with command events directly delivered to components (through each component's command channel).

These "Type II" aggregators would be similar to state machines. You would need for these something similar to Antidote's "ApplicationContext" to keep track of state. You could even program them with, say, the SMC's FSM language (instead of using BPEL, which is only for orchestrating web services in ESBs).

Or you could use some sort of Workflow engine. After all an aggregator just receives and sends events (and keeps state and access the model for data). So some sort of workflow mechanism may be helpful here?

May be is that the future of GUI development? Using some sort of declarative language to manipulate GUI behaviour, once a good set of macro-components is in place? Having workflow editors to program GUIs? Who knows. Maybe we'll have something similar to NetBeans MIDP Visual Editor for building J2SE GUI Applications.

This is a long one

Sorry for such a long post. It's lots of things to think of!

Now, what do you think? Which one would you prefer? Type I aggregators or Type II aggregators? You may already know my preference: I like simple things! ;-)

I'm wishing to discuss. Come on, participate. I'm working for a draft implementation and I'll let you know whenever is ready.

Happy Swinging,
Antonio

Comentarios:

I read your previous two posts, and posted comments...however, something with my RSS Reader, they did not get posted. I absolutely think "Type II" aggregators are the way to go. This way the aggregator does not have to change if the visual components change. If aggregator has to know about component type then if you have a textfield it calls, setText..but if it changes to JSlider, you need setValue...now you have to modify aggregator. So put one vote in for "Type II". Where do we go from here? ..also, any update on UITopics on java.net?

Enviado por codecraig en septiembre 23, 2005 a las 06:53 AM CEST #

Hi,

Yes, as you may know blogs.sun.com is still growing, these guys are building new great features in it. It seems we've been having trouble with uploads (during a few days I couldn't upload jar files, nor png files, etc.) and with comments too. These have been solved. Since the UITopics in java.net is under approval I'll release the source today for you to see.

Yes, Type II are the way to go. But maybe it's a long way, right? I'll think of it.

Cheers,<b/> Antonio

Enviado por Antonio en septiembre 23, 2005 a las 12:16 PM CEST #

Enviar un comentario:
Los comentarios han sido deshabilitados.
About

swinger

Search

Archives
« abril 2014
lunmarmiéjueviesábdom
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    
       
Hoy