main website home
  • About this blog

    This blog features updates, opinions, and technical notes from Caucho engineers about Caucho products, the enterprise Java industry, and PHP. Caucho Technology is the creator of the Resin Application Server and the Quercus PHP in Java engine. A leader in Java performance since 1998, Caucho is a Sun JavaEE licensee with over 9000 customers worldwide.
  • Tags

    ajaxworld bam candi cdi cloud cluster comet configuration deploy devoxx eclipse ejb embedded flash flex google app engine hessian hmtp ioc java ee 6 javaone javazone jms messaging newsletter nyjug osgi php pomegranate quercus resin resin 4.0 REST servlet sfjug silicon valley code camp spring testing training tssjs watchdog webbeans web profile websockets wordpress
  • Meta

    • Register
    • Log in
    • Entries RSS
    • Comments RSS
    • WordPress.org
« Caucho Newsletter
blog.caucho.com anniversary! »

BAM: Brokered Actor Messaging

caucho cloud

As part of the Resin 4.0 work, I’ve refactored and renamed the key BAM classes to better describe the architecture and roles. The key classes are SimpleActor and ActorStream.

BAM is a lightweight serializing messaging API, designed for small, bidirectional, interactive messages for applications like SAAS (software as a service) or online gaming. Resin 4.0 uses BAM/HMTP for its clustering protocols, including our distributed caching, JMS, and distributed deployment. BAM is designed to work with multiple wire protocols including HMTP (Hessian Message Transport Protocol) and XMPP (Jabber, eXtensible Messaging and Presence Protocol.)

Actors, Brokers and ActorStream

BAM is designed around a hub-and-spoke topology like a large delivery service such as FedEx, UPS or a postal service. The Broker plays the role of a major airline hub, like Chicago O’Hare or London Heathrow. The Actor is anyone sending or receiving packages, like a delivery customer or a shopping site like Amazon, or just someone sending a letter through the mail. With the hub-and-spoke architecture, the sending Actor sends a message to the hub, which delivers the message to the destination Actor, like delivering a mail from your house, to Chicago O’Hare to a friend’s house across the country.

The Actor is a generalized service and client. Because BAM is symmetrical, all clients and services can send and receive messages or RPC calls. So a “service” or “client” depends on an Actor’s capabilities or even on a particular request. You can design a service-oriented architecture using BAM by creating an Actor that receives service-oriented messages, or you can create a traditional RPC (remote procedure call) architecture by creating an Actor that receives RPC query calls. You can even create a server-push (comet) architecture, where a browser client receives server messages when available, like an efficient RSS service.

Your architecture using BAM depends on the message (one way) and query (RPC) payloads. BAM is object-oriented: the Java class of the message or query payload determines the service on the destination Actor. A RssUpdate message to a client might update a news headline, and a AddShoppingItem query might add an item to a shopping cart, returning the current shopping cart and price.

The ActorStream interface gives you access to all the packet types. A source Actor will send a message or query through the ActorStream to the Broker, and the Broker will forward the message or query through another ActorStream to the destination Actor.

ActorStream

If you’re learning BAM, ActorStream is the best place to start, because it centralizes the key BAM concepts in one interface. Each of the ActorStream methods sends a BAM packet: messages, RPC query, RPC result, or publish/subscribe requests. “to” is the JID address (jabber id) of the target Actor, “from” is your own Actor’s JID, and “payload” is the serializable Java payload you want to send.

Because each BAM packet type corresponds to a HMTP or XMPP (Jabber) packet, your ActorStream method directly matches the underlying wire protocol packet. A pure messaging system like might only use the message() packets, while a pure RPC system might only use the queryXXX() packets. A publish/subscribe system like an RSS news feed might use the presenceXXX() packets to subscribe and unsubscribe to the news feed, and use presence() to announce a client login, and use message() to deliver any updates.

A BAM packet is like a UDP packet: the “to” address uniquely identifies the target, the “from” address uniquely identifies the sender, and the “payload” contains the actual data.

Internally both sending and receiving uses the ActorStream as the underlying API, but receiving Actors will generally extend SimpleActor to implement their client or service.

package com.caucho.bam;

import java.io.Serializable;

public class interfactor ActorStream {
  public String getJid();

  public void message(String to, String from, Serializable payload);

  public void queryGet(long id, String to, String from, Serializable payload);
  public void querySet(long id, String to, String from, Serializable payload);
  public void queryResult(long id, String to, String from, Serializable payload);
  public void queryError(long id, String to, String from, Serializable payload,
                                  ActorError error);

  public void presenceSubscribe(String to, String from, Serializable payload);
  public void presenceUnsubscribe(String to, String from, Serializable payload);
  public void presence(String to, String from, Serializable payload);
  ...
}

SimpleActor

SimpleActor is the key base class that most applications will extend to receive messages, because it lets you annotate your receiving methods with packet annotations like @Message to automatically dispatch by the packet type and payload class.

The following trivial SimpleActor dispatches MyPayload messages to the myMessage method. This pattern is a typical SimpleActor implementation: each packet type and payload has a unique method responsible for receiving and processing the packet. All other packet types and payloads are automatically handled by SimpleActor, and are generally ignored for messages or return errors for RPC queries (because queries require a response or error.)

The @Message, @QueryGet, @Presence, etc. annotations exactly match the packet types. So ActorStream and the SimpleActor annotations mirror each other.

The payload class is your own Java serializable class, which contains the data for the request. So creating a service in BAM means defining a set of payloads and an Actor to handle those payloads.

package example;

import com.caucho.bam.Message;
import com.caucho.bam.SimpleActor;

public class MyActor extends SimpleActor {
  @Message
  public void myMessage(String to, String from, MyPayload payload)
  {
     System.out.println("received: " + payload);
  }
}

Summing Up

Hopefully, this post gives a good overview of the BAM architecture. Once you wrap your mind around the design, it’s a nice, clean system, but it may take a couple of times re-reading before all the pieces fit together. I’d recommend studying the ActorStream as the central interface, and look at each packet types and the JID addresses as the key concepts, thinking of each packet like an object-oriented UDP packet . Once you understand the ActorStream, the other pieces should fall into place.

Tags: actor, bam, hmtp, messaging, resin 4.0

This entry was posted on Tuesday, February 24th, 2009 at 1:20 pm and is filed under Engineering. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

One Response to “BAM: Brokered Actor Messaging”

  1. Caucho Technology » Blog Archive » BAM! Flash! (and Hessian) Says:
    March 12th, 2009 at 12:58 pm

    [...] and BAM. The Hessian side is now updated to be compatible with the latest Hessian 2 changes. As Scott mentioned, the BAM API and protocol has undergone some changes since the last revision, so I’ve [...]

Leave a Reply

You must be logged in to post a comment.


Caucho Technology is proudly powered by WordPress and Quercus®
Entries (RSS) and Comments (RSS).

  • HOME |
  • CONTACT US |
  • DOCUMENTATION |
  • BLOG |
  • WIKI 4 |
  • WIKI 3 |
  • Resin: Java Application Server
Copyright (c) 1998-2012 Caucho Technology, Inc. All rights reserved.
caucho® , resin® and quercus® are registered trademarks of Caucho Technology, Inc.
resin® is a cloud optimized, java® application server that supports the java ee webprofile ®