Skip to end of metadata
Go to start of metadata

Events in Dentaku are aggregations of information that fully contain information that allows the state of the application to transition between to states. Let's loosely define some of these terms to get started:

  • The state of an application is typically defined by the collection of all dynamic information that allows the running system to respond in the manner that it does. In a typical enterprise system, this state is completely contained in the persistent store, often a SQL database. Two identical instances of this application, running on separate hardware with separate databases, in turn respond differently when data in the persistent store is different. This could be as simple as a different address on a personnel record between the two systems.
  • In turn, the state of such an application could be further defined defined as a snapshot or backup of the database at a given instant in time.
  • State transition is the process of this aforementioned single state being left and a new singlular state being entered. A single state transition completely conforms to ACID transactional semantics, and as such, the rollback of a transition would restore the application to a point that it would be indiscernable that any changes had been attempted. In the case of updating the address of a personnel record, the rollback of this update would leave the system responding exactly as it had prior to the commit of the original state transition.
  • Finally, events are the full embodiment of the information required to affect the transition from one state to another. An event is the combination of the information required for a transition (say, the new home address of an employee) and a symbolic name for the transition itself – a command (for instance "update employee").

Clearly, in an application with thousands or millions of objects in the persistent store, each containing endless choices of data, the true number of states that are possible is also endless. Enumerating these states is meaningless in the context of an enterprise application, we are simply interested in the arbitrary state as defined by the snapshot of the persistent store at relative points in time. Imagining for a moment that a data snapshot had a little green light that glowed when the data in the persistent store (i.e., the state) was valid and referentially integral, the goal of our application would simply be to always keep the green light on. And in a perfect world with perfect programs, this would not be a problem, because there would be no mistakes.

Enter Reality

The reality of software development is that rigorous proof of all programs in a competitive marketplace is impractical. Attempting to rigorously prove the correctness of every production enterprise application is akin to organizational suicide when considered in the context of your lunch being eaten by a competitor as you do so. Software development has entered the realm of vocational trade, and combined with the complexity and size of the results, there are never enough programmers with classical formal skills that can write all the software that is demanded of the industry. All we can aim for is procedures and processes that reorganize the failure modes of a program such that they become more evident, including Test-Driven Development with full code coverage monitoring.

The idea that we have mission-critical code that we believe we have tested well but still has bugs has left many a manager awake at night, wondering about the repercussions. "Should more resources be applied to testing? What if there truly are no more bugs and those expenses were for naught? But what if there are bugs and our collection of data is rendered useless in the process?"

These questions are precisely the reason that you want to architect your program using events and develop with TDD! While TDD gives you a relative sense of security, events give you a disaster recovery plan.

Reconsider our event model. Starting with a virgin enterprise system, if we have a serialized stream of events from the first data that was ever committed to the database to the present, we are never in any danger of bad code permanently corrupting our data collection. Sure, there's no question that bad code could be deployed and the database rendered temporarily useless, but in a maintenence situation it is a simple matter to find the point in time when that bad code was deployed, roll back the persistent store to a state (backup) before that point, deploy the repaired code, and replay the event stream after that date. After replay of all events, we find that the database is repaired and when the application is returned to online state, it operates as it was designed to do, without further corruption.

Dentaku Architecture

Events are of primary importance to understanding the role of the Dentaku framework in your enterprise application. MVC is a very common architecture for server applications, but breaks down in large applications with event-based controller architectures because there is simply no support for events at this level. One option is to extend the definition of "good" MVC to contain this, but better is to simply build a lower level framework to embody this. That is exactly what Dentaku is – a framework to accept events from the controller, any controller, that is used for the application.

This is worth making special note. No matter the type of application front end, whether it is a web application using Struts or WebWork, a "fatter client" using applets, a true fat client running in it's own process space, or even another server application in an enterprise cluster, driving the state transitions of the application by events is completely agnostic of the client that is used to do so. This offers massive flexibility to the developer, even at the same time that it offers the operational robustness that was detailed earlier.

Development Support

Event modelling is the term that is used in the analysis of the application specifications and defines what functions the application is capable of. Very large applications will have a large number of events, and it is worth considering to start with how to generalize your events such that they are as granular as possible. It is also important to find the patterns within your commands for the events, and make sure that those patterns are globally subscribed to. In the end, you should have an event set that is consistent, predicatable and scalable.

Events in Dentaku can be modelled in UML and generated to code just the same as entity objects for the persistent store can. By doing so, the absolute functionality of the application is always current in the UML documentation, for the code is an artifact of the UML documentation, not the other way around. Because events can be generated from architectural drawings faster than they can be coded by hand, rapid prototyping is enabled. And because the event code is generated from templates, aspect-oriented crosscutting is provided to your code through the ability to modify templates, altering the code that is generated for all events on future builds. (Of course, this power is also provided to entity objects.)

Getting Started

Take a look at the example-model project, see how events are modeled in the UML, build the project, look at how the transforms in the Velocity scripts use the UML to create the event code in the final example-model code. Now, examine how the example-web application uses these events that are a part of the example-model jar to generate a CreateInvoice event in the CartAction of the Struts web application. Note how there are several Connector}}s available to dispatch the event; {{DirectConnector, used in the example, presumes Dentaku is running in the same JVM. EJBConnector, on the other hand, could be used to dispatch an event to a Dentaku application running in a separate JVM. An XML-RPC connector could be written just as easily.

Please post your questions and comments on this document to the user@dentaku.codehaus.org mailing list!

Labels
  • None