Publish and subscribe

Each process worker runs independently of other workers, and each worker should only access its own data and methods. This independence of workers works well for most solutions.

In some cases, it makes sense to allow workers to work together. As some examples:

  • A worker may be logically a part of another worker, and may need to pass data to its parent for the parent to complete.
  • One worker may need to know about the state of another worker before continuing.
  • It can be useful to make workers visible to additional processes that can then interact with the workers.

These scenarios are achieved through a publish and subscribe mechanism in which a worker publishes a message and subscribers, which may be other workers or groups, then decide how to deal with the message.

Defining a subscription

There are two parts to a subscription: defining what messages to publish to which processes, and then responding to the message within the group or worker than receives the message.

The response to the message is described in a later section.

There are three different types of definition of what should be published.

Group subscriptions are defined on the publication rules field of the group. The publication rules field list groups (or workers) that subscribe to messages published by this group. Each subscription is associated with a reference of the form processType/topic, which defines the combination of processType and topic that should be sent to the group. Either of these can be blank or set to "*" to indicate all process types or all topics. If there is no slash, the reference is assumed to be a process type. Add a suffix of "+" to inherit the subscription down the group hierarchy and for the rule to be applied to groups.

Owner connection subscriptions are defined on publication rules field of the connection group of the owner connection of the worker or group, which typically identifies the source of the worker. These work in the same way as other group subscriptions.

Worker link subscriptions are created automatically by linking workers using the Worker links field, rather than using a separate subscriptions field. The worker links field lists other workers (or groups), and gives each link a link type. Each of these workers will receive messages every time the worker publishes one. Also, workers that link to this worker will receive a message.

Publishing

Data is published from a worker using the Set step type and setting the publish property, either to the name of a topic or to true to indicate that the event type should be used as the topic. The publish can be used at the same time as setting other data, or as a separate step. The publish takes place asynchronously, and other processes may respond to the message after (or before) the worker process execution has completed.

The call to the subscriber always follows the same format. It has an action of @consume, and a data parameter which contains the subscription message in the "message" property.

{
"message": {
"messageIdentifier": "unique-message-identifier",
"reference": "worker.node.reference",
"processIdentifier": "worker-process-identifier",
"role": "role",
"processType": "process_type_reference",
 "publicationMode": "publicationMode",
"topic", "topic",
"status": "status",
"data": {.. data ..}
}
}
messageIdentifier Unique identifier for this message.
reference Node reference of the worker.
processIdentifier Worker's process identifier.
role Worker's role within the process, defaults to "owner".
processType The worker's process type reference.
publicationMode

The reason the message was published. This can be:

  • "self" for publishing to self.
  • "rule" for a group publication rule.
  • "owner" for an owner connection subscription.
  • "group" for publishing from a worker to a group.
  • "parent" for publishing from a group to a parent group, or from a worker to a parent worker.
  • "child" for publishing from a group to its child groups, or from a worker to its children.
  • "xxxx" for a worker link, where "xxxx" is the link type.
  • "-xxxx" for a worker back link (publishing to a worker that links to this worker), where "xxxx" is the link reference for the worker that links to this worker.

The publication mode may seem the wrong way around to the subscriber. For example, a message from a child will have a publication mode of "parent". Remember that the publication mode is the publisher's view of the reason, not the subscriber's.

topic

The topic of the publication. This is taken from one of three sources:

  • The value of the "publish" parameter passed during publication.
  • If the "publish" parameter is exactly true, the eventType set during publication.
  • If the eventType is not set, to null.
status
The current status of the worker.
data
The data associated with the publish.

Responding to messages

The @consume action can do anything. In many cases it will make sense to use the Evaluate step type to interpret the incoming message and route it accordingly. The @consume action should check processType, topic and publicationType to decide what to do. As a suggestion, these values can be meaningfully concatenated as processType.publicationMode.topic, e.g. "raise_order.owner.orderSent" would identify the orderSent topic from the raise_order processes which have as their owner the connection associated with this group, or "project_task.-wbs.finished" to indicate that a project task lower in the work breakdown structure has finished.

The message is passed in to the consumer as the message property of the data parameter, i.e. the message is obtained by:

JSON.parse(application.get('request').getString('data')).message;

A process may receive messages that it cannot process. These should be ignored and no error should be raised.

Subscribers can use the worker reference to call back to the worker, or pass the process identifier and role to a process module which can (assuming it is trusted) then call back to the worker.

Processes do not have to respond to messages sent to them. The @consume action is invoked with a "?" suffix, which means that the call will not fail if the subscriber does not have an @consume action.