Model-Glue Event Request Life Cycle

The typical Model-Glue event life cycle looks like this:

  1. The initial event-handler is executed.
  2. Any messages contained within the event-handler are broadcast.
  3. Any results contained within the event-handler are fired, and their events are queued.
  4. Any views contained within the event-handled are queued.
  5. The event queue is processed, and any queued events are executed, repeating steps 2-5 as necessary.
  6. Once all queued events have been executed, all queued views are rendered.

There are, however, a couple of exceptions to this general rule:

  1. If a <result /> has the redirect attribute set to true, the redirection to the event will occur immediately when the result is fired.
  2. Events arising from named results (e.g. <result name="resultName" do="otherEvent" >) will be queued before implicit results (e.g. <result do="otherEvent" >).

Furthermore, when these two cases are combined, the redirection will occur at the time that the named result is added by the message listener function, which could mean that some message broadcasts would be skipped (as would any other results and views).

As far as event types go, it might be helpful to conceptualize types as "wrappers" for an event-handler. Any broadcasts, results or views that are present in an event type will be merged into the event-handler, and placed either before or after the handler's own broadcasts/results/views blocks.

Therefore, this configuration:

<event-type name="sometype">
    <before>
        <broadcasts>
            <message name="beforemessage" />
        </broadcasts>
        <results>
            <result do="beforeresult" />
        </results>
        <views>
            <include name="beforeview" template="before.cfm" />
        </views>
    </before>
    <after>
        <broadcasts>
            <message name="aftermessage" />
        </broadcasts>
        <results>
            <result do="afterresult" />
        </results>
        <views>
            <include name="afterview" template="after.cfm" />
        </views>
    </after>
</event-type>

<event-handler name="someevent" type="sometype">
    <broadcasts>
        <message name="eventmessage" />
    </broadcasts>
    <results>
        <result do="eventresult" />
    </results>
    <views>
        <include name="eventview" template="event.cfm" />
    </views>
</event-handler>

would be functionally equivalent to this:

<event-handler name="someevent">
    <broadcasts>
        <message name="beforemessage" />
        <message name="eventmessage" />
        <message name="aftermessage" />
    </broadcasts>
    <results>
        <result do="beforeresult" />
        <result do="eventresult" />
        <result do="afterresult" />
    </results>
    <views>
        <include name="beforeview" template="before.cfm" />
        <include name="eventview" template="event.cfm" />
        <include name="afterview" template="after.cfm" />
    </views>
</event-handler>

Summary/Review

The order of execution for event-handlers is:

  1. broadcasts
  2. results
  3. views

A key thing to understand here is that while message listener functions are invoked at the time messages are broadcast, both events added via results and views are queued rather than being executed/rendered when the event-handler is processed.