Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
The most basic outline of the framework.  Have yet to create event table and flesh out API.  Still need to instantiate components.
  • Loading branch information
fingerskier committed Mar 26, 2013
1 parent e861639 commit ddc146a
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 1 deletion.
12 changes: 12 additions & 0 deletions .project
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Interlude</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
<nature>org.cfeclipse.cfml.CFENature</nature>
</natures>
</projectDescription>
24 changes: 24 additions & 0 deletions Application.cfc
@@ -0,0 +1,24 @@
<cfcomponent extends="Interlude">
<cffunction name="onApplicationStart">

</cffunction>

<cffunction name="onApplicationEnd">
</cffunction>

<cffunction name="onSessionStart">
</cffunction>

<cffunction name="onSessionEnd">
</cffunction>

<cffunction name="onRequestStart">
</cffunction>

<cffunction name="onRequestEnd">
</cffunction>

<cffunction name="onError">
<cfdump var="#arguments#">
</cffunction>
</cfcomponent>
17 changes: 17 additions & 0 deletions Interlude.cfc
@@ -0,0 +1,17 @@
<cfcomponent output="false">
<cfset this.logUnhandledEvents = false>
<cfset this.rebuildPerRequest = true>

<cffunction name="emit">
</cffunction>

<cffunction name="ignore">
</cffunction>

<cffunction name="on">
</cffunction>

<cffunction name="onApplicationStart">
<cfset registerComponents()>
</cffunction>
</cfcomponent>
63 changes: 62 additions & 1 deletion README.md
@@ -1,4 +1,65 @@
Interlude
=========

A ColdFusion Event System
An opinionated, event-based ColdFusion framework


The Basics
----------
Events are generated by your application
Your application is notified of events in one of several ways:
GET: URL.emit, data will be an aggregate of accompanying URL variables if they exist
POST: form.emit, data will be an aggregate of accompanying POST data if it exists
Internal: application.emit('event~name', data);
No matter how an event is triggered it eventually is handled by the internal event system
Listeners can be registered via application.on('event~name', method.path)
event-names are not case-sensitive
the dot-path to the handler function must be previously instantiated (see below)

Event data is optional, this would be any bits that logically accompany the event


Why?
----
Because it's far easier.
Traditional web-applications are also built on an event system: applicationStart, sessionEnd, pageRequest, etc... In a well-designed REST implementation each URI is, essentially, an event. However, we fail ourselves when we go beyond the basic framework events and try to fall back into a different style of programming: temporal, object-message-passing, whatever. An event system allows us to not only separate concerns, but also separate sequencing. This means writing testable units on a whim without having the mock-up huge chunks of the application beforehand.

API
---
on('event~name', 'com.dot.path');
the dot-path is optional when called from a constructor
emit('event~name', data);
data is optional
ignore('event~name', 'com.dot.path');
unregisters a listener
the dot-path is optional when called from within a CFC, in this case [if omitted] it is assumed to mean the current CFC/method

'com.doth.path'
this is of the form 'component.method', this is translated to application.com.component.method but that is transparent to you
nested directories/paths are fine


Example Application Structure
-----------------------------
Application.cfc
index.cfm
someView.cfm
com
controllers
aCtrl.cfc
bCtrl.cfc
services
someSrvc.cfc
anotherSrvc.cfc

This yields an auto-created structure in the application-scope: application.com
These component instances know nothing of each other.
The application keeps a table of events, and listeners registered to those events.


But...
------
Aren't I going to get lost in the weeds, with event registrations scattered about? Potentially, but that's up to you. You'll probably prefer to register events in onApplicationStart (or around that time) all at once. This will give you a nice map of your program flow and avoid frivolous event registrations.
Don't I have enough events already? applicationStart/End, sessionStart/End, requestStart/End, error, et al. This is a nice starting point but finer-grained events allow us to focus control toward an eventual end: events are handled when they change the model or emit a response event. This frees us from having to transition to another style of programming within our application.
How? The beauty of ColdFusion applications is that we have a variety of states that can be thought to create the current "mode" in which a user is operating. So, event-handler can mutate the application, session, and request objects to create the current application state (specific to each user). Additionally, each event might carry data with it that contributes to this "mode" and moves us toward handling the event.
What about unhandled events? No one will ever know...unless they read the logs. Unhandled events are logged if you so desire.

0 comments on commit ddc146a

Please sign in to comment.