Skip to content
andy-trimble edited this page Oct 27, 2014 · 3 revisions

BigIO Messaging

Overview

A message in BigIO is simply a plain Java object that is annotated with the io.bigio.Message annotation, and adheres to a few simple rules. The annotation and the rules ensure that the framework knows how to serialize the message so it can be sent across the network. Messages are serialized using the MsgPack protocol. MsgPack is essentially a generic way of bit-packing messages. This makes for extremely small messages and very fast encoding/decoding. The mechanisms for encoding and decoding are constructed at runtime via byte-code injection. This ensures common serialization with very minimal overhead.

Message Rules

Messages may contain any number of the following types:

  1. Primitive values
    • Integer
    • Short
    • Long
    • Boolean
    • Double
    • Float
    • String
  2. Lists of primitive values
  3. Maps of strings to primitive values
    • e.g., Map<String, Integer>, Map<String, String> etc.
  4. References to other objects marked with the Message annotation
  5. Lists of message objects
  6. Maps of strings to message objects
  7. Enumerations

The following rules apply to message objects:

  1. Objects that are not messages must be marked with the transient keyword.
    • e.g., for a logger private final transient Logger log...
  2. Lists and maps must be marked final and instantiated at the class level
    • e.g., private final List<String> aList = new ArrayList<>();
  3. Lists and maps may be nested
    • e.g., Map<String, List<Integer>> is an appropriate construct
    • e.g., List<List<List<Integer>>> is how a three-dimensional Matrix would be represented

Registering for Messages

All framework messaging occurs through the io.bigio.Speaker object. The Speaker defines the following methods for registering and un-registering message listeners:

To add a message consumer on a topic: public <T> void addListener(String topic, MessageListener<T> listener)

To remove a message consumer from a topic: public <T> void removeListener(String topic, MessageListener<T> listener)

To remove all message consumers on a topic: public <T> void removeAllListeners(String topic)

Receiving Messages

The io.bigio.MessageListener interface defines a message consumer. In order to receive messages, it is necessary to construct a listener and register it with the Speaker object. The following example demonstrates how this occurs:

speaker.addListener("SomeTopic", new MessageListener<SomeMessage>() {
    @Override
    public void receive(SomeMessage m) {
        // do stuff here
    }
});

Message listeners are notified asynchronously. Each notification will occur on a thread from a thread pool. However, in order to preserve resources for other consumers, it is important to offload any long operations into another thread. This will ensure that the resources are available for other messages listeners in the system.

Sending Messages

In order to send a message, it is only necessary to construct a message, populate the data and send it to the speaker for dissemination via the send(String topic, T message) method. Messages are sent to other consumers on a separate thread from that which calls the send method. Therefore, the send method is non-blocking.

It is also possible to send messages at some point in the future. Using the send(String topic, T message, long offsetMilliseconds) method, a message will be sent out at the specified number of milliseconds in the future. If a message needs to go across the network, the message is sent immediately and the framework on the receiving end will notify the consumers at the appropriate time. This ensures that messages are sent promptly and avoids many latency issues. If the offsetMilliseconds value is negative (i.e., strictly less than zero), the message will not be sent at all.

Clone this wiki locally