Skip to main content

On Manifold Affinity

AMPS includes a module to help implement a faucet-style publishing strategy.

With this strategy, publishers only activate for topics where there is known subscriber interest. The amps-action-on-manifold-affinity module monitors subscriptions that match a configured SubscriptionTopic regular expression, chooses an eligible publisher subscribed to a configured ControlTopic, and runs an action when that topic should be assigned, unassigned, or reported as having no eligible handlers.

A client connection indicates that it wants to participate in faucet assignment by subscribing to the ControlTopic. Each concrete topic that matches the SubscriptionTopic pattern is treated as an independently assignable topic.

Notice that although this action runs when subscriber interest changes, the On step does not, by itself, publish assignment metadata or adjust publisher subscriptions. It is up to the action configuration to publish the assignment information and up to the publisher clients themselves to respond to that information.

info

This module tracks subscriber interest and publisher availability on the local AMPS instance and runs an action when topic responsibility changes. However, it is up to the action configuration to alert publishers, and it is up to the publishers to respond to those alerts and begin or stop publishing for the assigned topics.

This action requires the following parameters. In addition to that, this module also accepts the optional parameters listed below:

ParameterDescription

MessageType

(required)

The message type of the monitored subscription topics and the control topic.

ControlTopic

(required)

The name of the control topic.

Any client connection that subscribes to this topic is considered eligible to receive faucet assignments. In most configurations, downstream Do actions publish assignment metadata on this same topic or a related control stream.

SubscriptionTopic

(required)

The PCRE topic pattern that identifies subscriptions to monitor.

Each concrete subscribed topic that matches this pattern is assigned independently.

Announcements

Controls how often the module emits assignment metadata.

The default value is default, which keeps notifications to the minimum needed to start and stop publishing: the first interested subscriber for a topic emits assign, the final interested subscriber emits unassign, publisher loss emits only the replacement assign, and a topic with no eligible publishers emits one no_handlers event.

The value all emits every assignment transition for each individual subscriber: each matching subscribe emits assign, each matching unsubscribe emits unassign, publisher loss emits unassign before reassignment, and a topic with no eligible publishers emits one no_handlers event per subscriber.

CoverageSubsetOption

When present, names a control-subscription option whose value is interpreted as a PCRE expression describing the subset of SubscriptionTopic values that this publisher can handle.

This option is typically a udo_* option such as udo_coverage supplied on the subscribe command for the ControlTopic. A publisher with multiple control subscriptions unions the coverage expressions from those subscriptions. If a control subscription omits the named option or provides an invalid PCRE value, that control subscription is ignored.

This module adds the following variables to the AMPS context:

VariableDescription
AMPS_CLIENT_NAMEThe name of the publisher client being assigned to or unassigned from the topic. This variable is omitted when AMPS_AFFINITY_ACTION is no_handlers.
AMPS_CONNECTION_NAMEThe connection id of the publisher being assigned to or unassigned from the topic. This variable is omitted when AMPS_AFFINITY_ACTION is no_handlers. This value is useful when the same client name reconnects and AMPS needs to distinguish the new connection from the old one.
AMPS_AFFINITY_ACTIONThe type of event. The value is assign when responsibility for a topic is assigned to a publisher, unassign when responsibility is removed from a publisher, or no_handlers when subscriber interest exists but no eligible publisher is available.
AMPS_TOPICThe concrete topic being assigned, unassigned, or reported as having no eligible handlers.
AMPS_SUBSCRIBER_CLIENT_NAMEThe client name of the subscriber whose subscribe or unsubscribe caused the event. This variable is only present when Announcements is all.
AMPS_SUBSCRIBER_CONNECTION_NAMEThe connection id of the subscriber whose subscribe or unsubscribe caused the event. This variable is emitted whenever AMPS_SUBSCRIBER_CLIENT_NAME is emitted, and only when Announcements is all.

Considerations and Limitations

The amps-action-on-manifold-affinity module has the following considerations for use:

  • Faucet state is tracked independently on each AMPS instance. In a replicated mesh of AMPS instances, each instance independently monitors SubscriptionTopic and ControlTopic activity.
  • Assignment is based on subscription interest, not on messages stored in a SOW topic. Each concrete topic that matches SubscriptionTopic is assigned independently.
  • Topics are load-balanced across currently eligible publishers by the number of topics already assigned to each publisher. Ties are broken by first-in activation order.
  • Assignments are sticky. Once a topic is assigned to a publisher, AMPS does not rebalance that topic to a different healthy publisher. The assignment changes only when the topic loses all subscriber interest or the assigned publisher unsubscribes from the ControlTopic.
  • If subscriber interest arrives when there are no eligible publishers, AMPS emits no_handlers. When an eligible publisher later subscribes to the ControlTopic, AMPS assigns any still-interesting unassigned topics.
  • When CoverageSubsetOption is configured, publishers can only receive topics that match at least one of their supplied coverage expressions.
  • AMPS_SUBSCRIBER_CLIENT_NAME and AMPS_SUBSCRIBER_CONNECTION_NAME are emitted together. In the default announcement mode, neither variable is present.

Faucet Configuration Example

The following example shows one way to use the amps-action-on-manifold-affinity module to notify publishers that they should begin or stop publishing symbol-specific topics. In this example, publisher processes subscribe to the symbol_faucet_control topic to enlist as handlers. When subscribers express interest in a topic under /symbols/, the action publishes an assignment message that the publishers can consume.

<Action>
<On>
<Module>amps-action-on-manifold-affinity</Module>
<Options>
<MessageType>json</MessageType>
<ControlTopic>symbol_faucet_control</ControlTopic>
<SubscriptionTopic>/symbols/.*</SubscriptionTopic>
<Announcements>all</Announcements>
</Options>
</On>
<Do>
<Module>amps-action-do-publish-message</Module>
<Options>
<MessageType>json</MessageType>
<Topic>symbol_faucet_control</Topic>
<Data>{"client_name":"{{AMPS_CLIENT_NAME}}",
"connection_name":"{{AMPS_CONNECTION_NAME}}",
"topic":"{{AMPS_TOPIC}}",
"event":"{{AMPS_AFFINITY_ACTION}}",
"subscriber_client_name":"{{AMPS_SUBSCRIBER_CLIENT_NAME}}",
"subscriber_connection_name":"{{AMPS_SUBSCRIBER_CONNECTION_NAME}}"}</Data>
</Options>
</Do>
</Action>

In this configuration, publishers receive a message whenever a subscriber begins or ends interest in a matching symbol topic. When the event is assign, the publisher begins publishing to that topic. When the event is unassign, the publisher stops publishing to that topic. If no publisher is available, the event is no_handlers. In Announcements=all mode, the payload also identifies the subscriber by both client name and connection id, which is useful when the same subscriber client name reconnects quickly.

Coverage Subset Example

The following example shows how to limit publishers to subsets of the monitored topic space. In this configuration, the publisher includes a udo_coverage option on its subscribe command to the control topic. AMPS uses that value as a PCRE expression to decide which concrete topics this publisher may be assigned.

<Action>
<On>
<Module>amps-action-on-manifold-affinity</Module>
<Options>
<MessageType>json</MessageType>
<ControlTopic>space_faucet_control</ControlTopic>
<SubscriptionTopic>/space/.*</SubscriptionTopic>
<CoverageSubsetOption>udo_coverage</CoverageSubsetOption>
</Options>
</On>
<Do>
<Module>amps-action-do-publish-message</Module>
<Options>
<MessageType>json</MessageType>
<Topic>space_faucet_control</Topic>
<Data>{"client_name":"{{AMPS_CLIENT_NAME}}",
"connection_name":"{{AMPS_CONNECTION_NAME}}",
"topic":"{{AMPS_TOPIC}}",
"event":"{{AMPS_AFFINITY_ACTION}}"}</Data>
</Options>
</Do>
</Action>

For example, if a publisher subscribes to space_faucet_control with the subscribe option udo_coverage=/space/C.*, that publisher can be assigned /space/C and /space/COBALT, but not /space/A or /space/E.