Galaxy Communicator Tutorial:

The Basics: How the Hub and Server Communicate, and What They Say

License / Documentation home / Help and feedback

An instance of the Galaxy Communicator infrastructure consists of potentially many processes, perhaps running on separate computers. These processes are arranged in a hub-and-spoke configuration. The spokes are known as servers, while the central hub is named (obviously enough) the Hub (capitalized throughout the documentation). Because none of these processes operates independently, it sometimes seems like it's necessary to learn everything at once. In this first lesson, we'll try to explain how these processes communicate, and how a configuration of servers and Hub get started.


Frames

Almost all communication in the Galaxy Communicator  infrastructure is in the form of a data structure called a frame. A frame is an attribute-value structure consisting of a name, a frame type (always "c" for clause, for historical reasons), and a set of pairs of keys and associated typed values. The keys, by convention, start with a colon (":"), but nothing in the infrastructure enforces this convention; the types for the values are drawn from a fairly standard defined set of types (integer, float, string, frame, list, etc.). These frames can be constructed using API calls, or parsed from a formatted representation, illustrated here:

In its printed representation, a frame is delimited by curly brackets "{}"; the type "c" appears immediately after the opening bracket, followed by the whitespace-delimited name, and finally the alternating keys and values are listed. We'll look at the details of the frame API and its printed representation later; all that's important right now is that you recognize the printed representations of frames when you see them.


Messages

A message is just a frame which is passed from the server to the Hub, or from the Hub to the server. These messages can be new messages, which initiate an action, or a reply to a new message. Either the Hub or server can send or receive new messages. In this section, we'll talk about what happens when a process receives a new message; later on,we'll talk about how a process might send a new message.

When a server receives a new message

From the point of view of the Hub, servers provide bits of behavior which the Hub can invoke by sending a new message to the server. These bits of behavior are called dispatch functions. When a server receives a new message, it looks for a dispatch function which it supports whose name matches the name of the incoming message frame:

The name of the incoming frame can be qualified by an "address", which tells the Hub which server to send the message to, or it can be unqualified. In the illustration here, the frame which the speech recognition server received has the address Recognizer and the dispatch function name Recognize. The server finds the named dispatch function and invokes it.

Dispatch functions can do a wide variety of things. They can send message replies, send new messages and optionally await message replies, or set up callbacks for backchannel connections called brokers. We'll cover all these topics later.

When the Hub receives a new message

In addition to routing message traffic among the various servers, the Hub can be provided with simple scripts called Hub programs. These Hub programs are sequences of rules which dictate which dispatch functions are invoked on which servers, what order they're invoked in, and under what conditions.

When the Hub receives a new message, it searches for a Hub program whose name matches the name of the incoming message. If it finds a program with that name, it invokes the program. This is called a scripted interaction. If the Hub doesn't know of a program with the given name, it searches for a server which provides a dispatch function with the given name, and relays the message it received directly to the server which provides the dispatch function. This is called a scriptless interaction. If neither a program nor a server is found, the new message is discarded.

This illustration provides an example of a scripted interaction:

In this illustration, the audio server sends a message named FromAudio to the Hub, which knows of a program with that name. The program has a rule which tells the Hub to send a message named Recognizer.Recognize.

A simple message sequence

If you've guessed that the message the Hub is sending in these examples is the same as the message the server is receiving, you're right:

So firing a rule in a Hub program is one way that the Hub can send a new message. Later on in this lesson, we'll learn about the other ways that new messages can be sent.


Starting up a Galaxy Communicator system

In order to run a configuration Galaxy Communicator processes, you have to start up all the processes: all the servers, and the Hub. The most convenient order for starting these processes depends on the Hub. In some cases, the Hub will contact the servers, and in other cases, the servers will contact the Hub. The details of this initialization sequence can be controlled in a number of complex ways, but we'll describe a simple case here.

Step 1: Servers start up

Typically, the first thing that happens is that the servers which the Hub will contact start up:
These servers will set up a port to listen for connections from a Hub.

Step 2: Hub reads program file

Typically, the Hub starts up next. When the Hub starts up, it reads a program file (specified on the command line with the -pgm_file directive), which contains:
If the Hub is supposed to contact a server, the program file will list the host and port the Hub should contact the server at. In this case, the Recognizer server is listening on port 15000 on the local host.

Step 3: Hub and servers contact each other

Now, the Hub contacts the servers it's supposed to contact, and starts listening for connections from servers which are supposed to contact it. When the Hub and server make a connection (no matter which side initiates it), the Hub sends a connection-specific initialization message named reinitialize, which executes the reinitialize dispatch function on the server (if it's defined).
In this illustration, the Hub is contacting all the servers except for Audio, which contacts the Hub at some later point.


Running a Galaxy Communicator system

Once the Hub has contacted the servers it's supposed to contact, the system begins its normal operation. During normal operation, the Hub and servers wait for the arrival of new messages. So where do these new messages come from?

When the Hub receives a new message: tokens and rules

Before we talk about where new messages come from, we need to go into a little more detail about what happens when the Hub receives a new message.

Each new message specifies whether the process that sent it wants an answer back or not. For each new message, the Hub creates a token, which is initially just a copy of the incoming message frame:

At this point, the Hub looks for an appropriately named Hub program. If the Hub doesn't find such a program (a scriptless interaction), the Hub relays the message to a server which provides a dispatch function named by the incoming message, and if the original sender wants an answer back, the Hub relays the reply from the dispatch function provider back to the original sender. In this case, the only information in the token that the Hub uses is whether the original sender wants an answer back.

If the Hub does find an appropriate Hub program (a scripted interaction), the token becomes the memory state of the Hub program, which is updated, step by step, by the rules in the program. The rules contain conditions under which the rules should be fired, instructions for constructing a new message to be sent to a server, and instructions for how to use the reply from the server to update the token. When the program terminates, the current token is returned to the original sender, if the original sender wants an answer back.

First new message source: the initial token

So we've already seen the two ways way the Hub generates a new message for a server: by firing a rule in a Hub program, or by relaying a message to a server in a scriptless interaction. In most cases, the new message which causes the Hub to do this comes from a server, but there is one crucial case in which the message comes from the Hub itself: the initial token.

The initial token is a frame, declared in the Hub program file, which is processed immediately after the Hub contacts the servers it's supposed to contact. This frame is treated as a new message received by the Hub, and is processed accordingly. So one way to generate a new message is to specify an initial token.

This is a fairly crude and unreliable way to generate a new message, though. First, the initial token is only processed once, and like all new messages, if it can't be processed, it's discarded. So if you have servers which contact the Hub which are crucial to the execution of the initial token, chances are they won't connect in time, and the wrong things will happen. So while the initial token is valuable for one-time system initializations (and for demonstration purposes), it's not a reliable run-time source of new messages.

Second new message source: reinitialize

We noted that when a server receives a new message and executes a dispatch function, it can in turn send a new message to the Hub. But this process can seem circular: the Hub sends a new message to a server, which sends a new message to the Hub, which sends a new message to a server, and on and on. We've seen one way this process can start: via the initial token. Can this process start from dispatch functions?

The answer is yes. Remember that when the Hub and server establish a connection, the Hub sends an initialization message to the server named reinitialize, which will then invoke the reinitialize dispatch function. This means that this dispatch function is called without the Hub needing to receive a message.

Since reinitialize is called every time a connection is established, it's more reliable than the initial token. First, it happens more often, and second, the timing of the dispatch function is clearly defined relative to server connection time. So for example, a batch processor could fire off its first batch processing request from the reinitialize dispatch function, and fire off each successive request upon receiving the result of the current request, until the batch process is complete. But this source of new messages is still limited; it's once per connection establishment.

Third new message source: user gestures

The third source of new messages is by far the most common: user gestures. The Galaxy Communicator infrastructure is designed for human-computer interaction, and most such interactions ultimately originate with the user, via a mouse click, microphone input, typed input, pen gesture, or some other UI action. The Galaxy Communicator infrastructure is designed to interact gracefully with processes which are connected both to a Hub and to the user in some way, and you can write these processes to translate user gestures into Galaxy Communicator messages.


Summary

In this introductory lesson, you've learned the basics about a wide range of elements of the Galaxy Communicator infrastructure: In the remainder of this tutorial, you'll learn enough about each of these elements to allow you to build your own Communicator-compliant system.

Next: Our first tool: the process monitor


License / Documentation home / Help and feedback
Last updated September 10, 2001