Namespace: topics

Session. topics

Topic control feature.


Provides methods to change and update the topic tree stored on the server.

Example

// Get a reference to topic control feature
var topics = session.topics;

Methods

add(path, supplied, initial) → {Result.<Session.topics.TopicAddResult>}

Add a topic to the server at a specific path. This returns a Result.

The path should be a string. To express hierarchies, / can be used as a delimiter. This allows topics to be nested and grouped below each other. For example, session.topics.add('foo/bar'); will create two topics, foo and bar, with foo acting as the parent of bar.

When a topic is created, it must be of a particular type, which constrains the kind of values that the topic will allow. This type can either be explicitly provided, or inferred from a default value.

Adding from value

The simplest way to add a topic is to provide a value. The derived types are described below:

Value type Topic type Metadata Initial value
DataTypes.JSON or JSON object Session.topics.TopicType.JSON Not applicable The supplied value
DataTypes.Binary or Buffer Session.topics.TopicType.BINARY Not applicable The supplied value
RecordContent Session.topics.TopicType.RECORD Metadata.RecordContent The supplied content
String Session.topics.TopicType.SINGLE_VALUE Metadata.String The supplied value
Number Session.topics.TopicType.SINGLE_VALUE Metadata.Integer or Metadata.Decimal, depending on the decimal format of the number. String representation of the supplied value

Adding from topic type

It is possible to directly specify the type of the topic to create, without an initial value. In this case, just provide a string path and a Session.topics.TopicType.

Adding from metadata

To explicitly set the desired metadata type, provide a Metadata instance, which can be constructed from the diffusion.metadata namespace. Optionally, a value corresponding to that same metadata definition can be provided as the third parameter, to be set as the initial topic value.

If the topic was added, or a topic already exists with the same path and type, the operation will succeed. If there is a problem with adding the topic, then the result will be rejected with the error provided.

If any sessions have already subscribed to the same path that a topic is created for, they will receive a subscription event once the topic is added, and an update event with the initial value (if supplied).

If the session is closed when calling this method, the returned result will be rejected.

Failure

If the operation fails a TopicAddFailReason is provided.

Parameters:
Name Type Argument Description
path String The topic path to create.
supplied Object | Session.topics.TopicType | Metadata <optional>
The supplied topic type/value.
initial Object <optional>
The initial topic value (if using metadata).
Returns:
A Result.<Session.topics.TopicAddResult> for this operation
Type
Result.<Session.topics.TopicAddResult>
Examples
// Create a stateless topic
session.topics.add('foo/bar');
// Create a topic with an initial value
session.topics.add('foo/baz', "initial value");
// Create a topic with a datatype value
var value = diffusion.datatypes.json().from({ "hello" : "world" });

session.topics.add('foo/json1', value);
// Create a topic with a JSON value directly
session.topics.add('foo/json2', { "hello" : "world" });
// Create a topic with a Topic Type
session.topics.add('foo/binary', session.topics.TopicType.BINARY);
// Create a topic using metadata and an initial value
var metadata = new diffusion.metadata.RecordContent();

// ... establish metadata fields

var builder = metadata.builder();

// ... add content to builder

var value = builder.build();

session.topics.add('foo/bing', metadata, value);
// Handle the add topic result
session.topics.add('foo/bob').then(function(result) {
    console.log('Topic added: ', result);
}, function(error) {
    console.log('Topic add failed: ', error);
});

addMissingTopicHandler(topicPath, handler) → {Result.<undefined>}

Register a MissingTopicHandler to handle requests for a branch of the topic tree.

The provided handler is called when a client subscribes or fetches using a topic selector that matches no existing topics. This allows a control client to intercede when another session requests a topic that does not exist. The control client may create the topic, perform some other action, or do nothing, before allowing the client operation to proceed by calling proceed(). Alternatively, the control client can call cancel() to discard the request.

A control client can register multiple handlers, but may only register a single handler for a given topic path. See MissingTopicHandler#onRegister. A handler will only be called for topic selectors with a path prefix that starts with or is equal to [email protected] topicPath}. If the path prefix matches multiple handlers, the one registered for the most specific (longest) topic path will be called.

If the session is closed or the handler could not be registered, the returned Result will call its failure callback, and the handler's MissingTopicHandler#onClose or MissingTopicHandler#onError method will be called.

Parameters:
Name Type Description
topicPath String identifies a branch in the topic tree
handler MissingTopicHandler specifies the handler for the specified branch (unless overridden by a handler registered against a more specific branch)
Returns:
A Result.<undefined> for this registration
Type
Result.<undefined>

registerUpdateSource(path, updateHandler) → {Result.<undefined>}

Register a handler to provide exclusive updates for a particular branch of the topic tree. Once successfully registered, the handler will be called with lifecycle callbacks. This grants this session sole access to publish updates to topics at or under the branch used for registration.

If no other handlers have been registered for the topic path, the handler will enter the active state. This provides an [email protected] updater} which can then be used to publish updates for topics at or below the registered topic path.

If there is an existing handler for the topic path, the handler will be put into the standby state. This indicates that the handler is registered but does not have access to publish updates. Once all previously registered handlers are closed, this handler will transition to the active state.

The handler will be closed if the session closes or [email protected]#close updater#close} is called. This is a terminal state from which no further state transitions will occur. When a registered handler is closed, if there is another handler registered by a different session, this next handler will transition to an active state.

Handlers cannot be registered above or below the topic path of any other registered handlers. Attempting to do so will close the handler.

Parameters:
Name Type Description
path String The topic path to register an update source for.
updateHandler TopicUpdateHandler handler specifies the handler for the specified branch (unless overridden by a handler registered against a more specific branch)
Returns:
a Result.<undefined> for this operation
Type
Result.<undefined>
Example
session.topics.registerUpdateSource('foo/bar', {
    onRegister : function(topicPath, unregister) {
        // The handler has been registered

        // Unregister the handler
        unregister();
    },
    onActive : function(topicPath, updater) {
        // Now that we're active, we have sole write access for all topics under 'foo/bar'
        updater.update('foo/bar/baz', 123).then(function() {
              // Updates return a promise just like session.topics#update
        });
    },
    onStandby : function(topicPath) {
        // The updater is registered, but another updater currently holds the active state.
    },
    onClose : function(topicPath) {
       // The updater is closed
    }
});

remove(path) → {Result.<undefined>}

Remove a topic from the server at a specific path.

If there are any topics below the path being removed, they will also be removed.

For every topic that is removed, an unsubscribe event will be fired for each session subscribed to that topic.

In future versions of Diffusion, this method will be changed to behave in the same manner that Session.topics#removeSelector currently does.

Parameters:
Name Type Description
path String The topic path to remove
Returns:
A Result.<undefined> for this operation
Type
Result.<undefined>
Examples
// Remove the topic at 'foo/bar'
 session.topics.remove('foo/bar');
// Remove all topics under 'foo'
session.topics.remove('foo').then(function() {
    // Successfully removed
}, function(err) {
    // There was an error removing the topic
});

removeSelector(selector) → {Result.<undefined>}

Remove one or more topics at the server.

The topics to remove will depend upon the nature of the topic selector specified. If the selector does not have descendant pattern qualifiers (i.e. / or //), only those topics that exist at paths indicated by the selector will be removed and not their descendants. If a single / qualifier is specified, all descendants of the matching topic paths will be removed. If // is specified, all branches of the topic tree that match the selector (i.e topics at the selected paths and all descendants of the selected paths) will be removed.

Deprecated since 5.9. This method will removed in future versions of Diffusion, with equivalent functionality to be provided by Session.topics#remove.

Parameters:
Name Type Description
selector String The selector specifying the topics to remove
Since:
  • 5.9
Returns:
A Result.<undefined> for this operation
Type
Result.<undefined>
Examples
// Remove the topic at 'foo/bar', leaving descendants
session.topics.removeSelector('>foo/bar');
// Remove the topic at 'foo/bar' and all descendants
session.topics.removeSelector('?foo/bar//');

removeWithSession(topicPath) → {Result.<Session.topics.RemoveWithSessionResult>}

Register a deferred action to remove a branch of the topic tree when this session is closed.

A removal action can be registered at any point in the topic tree, but can not be placed above or below existing registrations. An error event will be emitted if the server rejects the registration.

When this session is closed, regardless of reason, this topic and all topics below it will be removed from the topic tree.

Multiple sessions can request that the same branch be removed. If a branch has multiple registrations, then the marked topics will not be removed until all registered sessions have been closed.

When registration is successful, the Result will call the success callback with an object representing the registration with the property function deregister that can be called at any point to remove this registered action. The deregistration function returns a new Result.

If the session is closed when calling this method, the returned result will emit an error event.

Parameters:
Name Type Description
topicPath String The path of the topic tree to remove
Returns:
Type
Result.<Session.topics.RemoveWithSessionResult>
Example
// Remove all topics under 'foo'
session.topics.removeWithSession('foo').then(
    function(registration) {
        // Registration complete
        
        // Deregister this action
        registration.deregister().then(
            function() {
                // Deregistration complete
            },
            function(err) {
                // Failure while deregistering
            }
        );
    },
    function(err) {
        // Could not register
    }
);

update(path, value) → {Result.<String>}

Update a topic on the server with a new supplied value. If the update is succesful it will emit a complete event, and any sessions subscribed to the same topic will be notified of a topic update.

The value provided will be internally handled according to the same rules as defined for values passed to Session.topics#add. If a value is of an incompatible type for the topic being updated, then the update will be rejected.

It is necessary for the topic to exist. An error event will be emitted if the update was not successful.

If the session is closed when calling this method, the returned result will also emit an error event.

Failure

If the operation fails a UpdateFailReason is provided.

Parameters:
Name Type Description
path String The topic path to update
value Object The value to update the topic with
Returns:
A Result.<String> for this operation. The value is the topic path that has been updated.
Type
Result.<String>
Examples
// Update topic 'foo/bar' with content 'baz'.
session.topics.update('foo/bar', 'baz');
// Update topic with JSON content
var content = diffusion.datatypes.json().from({ "foo" : "bar" });

session.topics.update('foo/bar', content);
// Update topic with content from metadata
var builder = metadata.builder();

builder.add('record', {
    field : 'hello world'
});

var content = builder.build();

session.topics.update('foo/baz', content);

Type Definitions

RemoveWithSessionResult

Type:
  • Object
Properties:
Name Type Description
deregister function function to remove this registered action

TopicAddResult

Type:
  • Object
Properties:
Name Type Description
added Boolean whether the Topic was added or not
topic String the Topic path that was used