 |
 |
This document
describes basic requirements for the Barracuda Event model layer. We believe that
an MVC system has a fundamental dependancy on an underlying Event Framework. If you cannot
generate, deliver, and handle events reliably, it will be very difficult to build an
effective MVC layer (or a Component model!). Consequently, we focus our attention first on
the core requirements for a Web-App Event Model. After this, we can identify the
requirements for an effective MVC Framework, followed thereafter by an HTML Component
framework.
Overview
In the web-application paradigm, events typically originate on the client and are
handled on the server. There are also cases where they would be handled entirely on the
client (by a scripting language), or where additional events might be both generated and
handled on the server. There are no cases where events on the server would be handled on
the client, because the server has no way to initiate a callback to the client.
Most web-app frameworks do not have a distinct event model. We believe a robust event
model is a key ingredient for building a truly powerful presentation framework. The
purpose of this document is to try and identify the key requirements for such a web-app
event notification framework. Ideally, we want to keep this as simple as possible (making
it easy to understand and use) but also make it flexible enough to work for a number of
different application domains (including those we haven't thought of). The key is to
accurately identify the essential requirements.
Keep in mind that an event framework by itself is useless! It's what you can build with
it that is really interesting. The real value of an event model will be in the
presentation frameworks that build on it. Consequently, much of what we're talking about
here needs to be considered from an abstract perspective. If you are looking for
"presentation layer" specifics, you won't find many (they come next). Instead,
you will find an attempt to capture the essence of a very generic web-app event
model. Much of the design comes from looking at stated approaches to event handling
(like the JDK 1.1 event model), and trying to understand the key differences between the
two paradigms.
A final note on terminology -- throughout this document I'm using the terms "Event
Listener" and "Event Handler" interchangably. I use these terms as you
would in traditional stated GUI developement -- an event listener simply represents a
chunk of code that expects to be notified when an event occurs.
Key Differences
There are several key paradigm differences between a traditional stated event model,
and a web-app event model:
Number of Events - In a client-server event model,
there are many events generated per user action; in the web-application model there will
probably be relatively few events generated per user action (although there may often be
more than one). This doesn't have huge ramifications, but it's worth noting because it
will impact the overall design, and it's different than stated event models.
Generating Events - In stated event models, the
components themselves actually generate the events and assume responsiblity for notifying
all registered listeners. In the web-app model, client-side components are usually HTML or
client script, and their only ability to generate an event is usually limited to
dispatching a single URL request (ie. they can't send out a URL request for every
listener).
Consequently we must rely on a server-side component to map HTTP requests
to events, and then deliver the events to interested parties on behalf of the client. We
can safely assert that an HTTP request only needs to be able to deliver one client event
to the server. Susbsequent events that might be generated in response to the original
event would all originate on the server (and hence would not need to be transported via
HTTP).
Event Registration - In a stated model, listeners
register for events directly with an instance of the object that generates them. In the
web-app paradigm, there is really no way to register directly with an object instance,
because in many cases the client object generating the event will not be local to the JVM
(or have the capacity to do event notification). Consequently, we must find a way to
express an Event as a URL. This requires capturing a) the class of Event and b) the
listeners who need to be notified when that occurs. The easiest way to do this is to
encapsulate the event name in the URL itself, and to pass listener information as HTTP
parameters.
Responding to Events - In the stated-app model, events
are often times just ignored. For instance, if there are no listeners no one gets notified
and it's not a big deal. In the web-app model, some events (like those generated through
HTTP) must have a response because the transport protocol requires it. The framework needs
to be able to gracefully handle these types of situations.
Deferred Delivery of Events - In the web-app paradigm,
events may be generated on the server that require the client view to be updated. However,
this cannot occur until the client generates another request (which won't happen until
some other event occurs on the client). For example, if a users session times out on the
server, the user will no know this until they actually try to do something in their
browser (which may be never). Consequently, we must have some mechanism for handling the
deferred delivery of events, or for providing equivalent capabilities.
High Level Goals
Considering the abstract nature of the problem domain, let's start by trying to
describe the general characteristics we are looking for in an event framework.
We are primarily interested in Events that originate on the client and need to be
handled on the server. Make it possible...
- for developers to have a "real" event model for web-apps, where events are
true Java objects delivered to interfaces that implement the appropriate event listeners
- for client-to-server event notification to occur over HTTP, while not excluding other
forms of communication (ie. SMTP, SMNP, etc) from using and interfacing with the event
model
- for a client side component (HTML, Javascript) to deliver an event to the server through
one HTTP req/resp connection (regardless of how many listeners need to receive the event)
- to represent events within the URL in such a way that they can be mapped directly to an
instance of the Event on the server
- for an event to target specific listeners on the server (ie. so only they receive the
event) OR to target anyone interested in the event.
- to eliminate custom dispatching code -- the developer should not have to write case
stmts to instantiate events or to map them to the appropriate handlers
- to maximize performance by dispatching events to listeners without using reflection. If
reflection is required, minimize it's impact by providing a pooling mechanism.
- to distinguish between request events (something happened) and response events (a
response needs to be generated and sent back to the client)
- to dispatch both kinds of events using a Model 2 pattern, whereby request events
correspond with Controllers and response events correspond with Views
- for event handlers to fire additional events which get handled by other event handlers
- for event listeners to be loosely coupled...if one listener does logging, one does
validation, and one generates output, none of these should have to know about one another
- to proprogate unhandled events up an event heirarchy (like Exceptions), so that we can
create event handlers which only need to know about these events (not about the underlying
specific events).
- to dispatch events down an event hierarchy (Polymorphically), so that if I fire FooEvent
all its parent events will be fired first (because FooEvent is in fact an instance of
those events)
- to handle deferred delivery of server-side events (so the next time the client does
something, the effects of the event which already occurred on the server can take priority
over the client generated event)
- to create Java objects that provide a server-side encapsulatation of client side
components (HTML/WML/etc ) and are capable of generating "events"
- to add multiple event listeners to these Java objects that will receive the event when
the action occurs (ie. Button, Link, Image pressed)
- to insulate both designers and developers from the semantics of event
delivery...ultimately we should just be able to add listeners to components and know that
when the component generates an event the listeners will get invoked
- for events to be dispatched through a central "event broker" which maps URL
requests to events and delivers them to all interested parties
- for an application to use multiple event brokers, each of which might have custom
dispatching policies for events
- for the entire event system to be based on interfaces, so developers can create custom
dispatching implementations without impacting applications that rely on the event model
Of course there will also be Events that originate and are handled entirely on the
client...we'll address these later.
Event Requirements
In General...
- Simplicity - make it easy for developers to use/understand.
- Scalability - handle large numbers of clients/connections, spread
across multiple machines. This means we want to minimize what needs to be stored in
memory, and make it possible for multiple classes to re-use instances of event handlers
and events (although not requiring them to do so)
- Throughput - maximize event delivery throughput by avoiding slower
methodologies (ie. reflection) and minimizing the length of the event delivery chain (from
reception to handler as quickly as possible)
- Reliability - the system should be highly reliable and come with a full
regression test suite that operates on the core interfaces. This will allow developers to
validate new implementations by simply plugging them into the existing test suite.
- Pluggability - make it possible for developers to plug in their own
custom functionality to all aspects of the event model
Specifics...
- Event Types - There are two fundamental types of events:
- Request events
- Response events
- Event Queue - The event queue's primary responsibility is to contain
events. At a minimum, it must be able to
- provide an ordered listing of unprocessed events in the queue
- allow new events to be added to the queue
- carry state information for communication between listeners and the gateway
- indicate whether or not the queue requires a response to be generated
- Event Context - An event handler must be given access to basic
information in order to process an event. At a minimum, it must have
- access to the event (and any specific information that pertains to that event)
- access to the gateway specific information that accompanies the event (like HTTP
Request/Response objects if it orginated through an HTTP gateway)
- the ability to determine if the event has been handled, to mark it handled when complete
- the ability to determine if a response has been generated
- the ability to fire additional events
- Event Generation - Events may be generated in 2 ways
- User Action - ie client-side components (button, link, etc)
- Programatically - by event handlers (either client or server side), often (but not
necessarily) in response to a previous event
- Events Handling...
- Client side events may be handled either on the client or server side
- Server side events must be handled on the server (since there is no way to do a callback
to the client)
- There must be a mechanism to provide default handling of unhandled events that require
to be handled (ie. re-render the view, present an error page, etc)
- Event Delivery & Processing...
- There may be one event per client gesture (J2EE lingo)
- There may be zero to many specific listeners on an event
- For every event, each specific listener should be invoked based on the order the
listeners were added
- If there are no specific listeners, the event should be delivered to all generic
listeners that have expressed an interest in that class of event
- Listeners can respond to an event in many ways: they can generate a response, update an
underlying model, ignore it, or fire a new event
- Once a response--if needed--has been generated for the client, the event may be marked
handled
- Event delivery should only continue to remaining listeners that have requested to be
notified always, regardless of whether the event has been handled or not
- Events should be able to indicate whether or not they must be handled. If this is
required and they are not handled, they should be treated like an exception and the parent
event should be added to the queue
- Events should be able to indicate whether or not they should be handled polymorphically.
A polymorphic event would cause all parent events to be fired prior to the event itself
being dispatched, because the event in question is an instance of all it's parent events.
This
approach (#s 1-9 above) allows for 6 distinct scenarios:
- a) individual event handlers assume responsibility for generating the client response
and completely handle the event and response tasks
- b) individual event handlers simply update the model and fire additional events so that
someone else will handle the client response.
- c) individual event handlers simply update the model and rely on a default event handler
to render the client response
- d) some event handlers act as logging mechanisms for events, always receiving events but
not ever marking them handled
- e) developers provide custom error handlers simply by listening for known Error Events
(ie. no overriding the dispatcher necessary) (#8 above)
- f) developers can provide for deferred delivery of events and pre-dispatch validation by
listening for events higher up in the event chain (#9 above) and adjusting the contents of
the event queue accordingly
- If a server-side event listener generates a new event, it should only do so by adding it
to the dispatcher's event queue (thus preventing deadlock)
- Ideally, event processing should not involve reflection (performance hit) or case
statements (developer intensive)
Scope Boundaries
There are some things which are beyond the scope of the Barracuda project.
- Client side event handling - We are not addressing this now, although we intend to
in the future with a Javascript framework.
- Applets - Barracuda is about creating a presentation layer for web apps. It's not
intended to handle presentation issues for applets (where you usually can take advatange
of stated presentation techniques typically found in client-server component models like
Swing).
Open Issues
None at this time. |
 |
 |