Thursday, March 25, 2010

Queue Manager 4 - Design Notes on Bots and Sessions

QM4 Home

Definitions of terms (good for navigating class names in the Jumpstart codebase):

“Bot”: A process which runs as a thread and fields messages for a particular Application. For-instance, an Interview Bot might be logged in under Sametime and XMPP usernames, and will field all messages for a particular instance of the Interview application (a given Navigator tree). Bots typically receive user input from the firing of their “TextReceived” method.

“Session”: A process which also runs as a thread and fields messages from a particular user in a particular application. The application logic is usually not in the bot class (except for very simple one trick pony bots.). When a bot receives a message, it will look in a table it keeps of users it has seen before, and if there is already a session for that user, it will dispatch the message to that session. If not, it will spin up a new session and start it in a new thread.

So there is a one -to-many relationship between Bots and Sessions.

Bots are very tied to the IM-style interface, in that they get their input from the firing of TextReceived, which happens when they register with one or more IM services (Sametime, Facebook, etc).

A design goal of the framework was to have applications and services be re-usable in a wide variety of contexts. One possible way Bots could have communicated with Sessions is by firing a TextReceived message in the session. TextReceived is great for the IM world, but it is limited in the data that is passed. It is not a great method for communicating between modules. For-instance, It would be nice to send an arbitrary object along with a message, containing links to conversation history, etc. To get low overhead with max flexibility, messages are dispatched from Bots to Session via the ITQueue interface. So when a Bot receives a message, it puts in on the ITQueue of the appropriate Session, or creates a new Session and associated Queue if it is a new visitor.
The run loop of the Session thread simply pulls messages off the queue. Because the Session was passed the MsgServices used by the Bot on startup, it can send responses to the user directly. When the user responds, the message will flow through the bot and back to the appropriate session.

Sessions and Bots can be mixed in matched in terms of being in Groovy or Java. A new Interview Bot could be written in Groovy, but dispatch messages to the existing Java-based InterviewSession. A queue bot could be written in Java, but dispatch to a QueueSession class written in Groovy. One of the keys to maintaining this flexibility is to have bots in either Groovy or Java extend MultiService Bot and sessions extend MultiServiceSession.

You don't “have” to adhere to the above architecture, you can write a Bot in Groovy or Java to do whatever you want, and use the Jumpstart classes as support classes.. But you will get more proven code under the hood, more monitoring and logging “for free” in the future and a more maintainable system if you follow the above approach in creating new applications.

No comments: