Stability: 1 - Experimental
Send messages between memory domains (tart module)
The tart-marshal
module provides a mechanism for sending messages between memory domains. This involves marshalling each message, converting local actor references into unguessable tokens for transmission across a network.
domain0: domain1:
+----------------+ +----------------+
| | ping | ping |
| +--------- ( token [ . . . . [ proxy ) <--+ |
| v | | | |
| ( ping ) | | ( pong ) |
| | pong | pong | ^ |
| +--> ( proxy ] . . . . ] token ) ---------+ |
| | | |
+----------------+ +----------------+
The process begins by asking a domain to generate a token representing a remote reference to a local actor. The token is then used to create a proxy in another domain. The proxy marshals and forwards messages across a network to a remote actor in the domain which generated the token.
On receipt of a marshalled message, the destination domain replaces any tokens with references to local actors, and delivers the message to the target actor (identified by the token used to create the proxy). Unrecognized tokens are replaced by new local proxies for remote references.
To run the below example run:
npm run readme
"use strict";
var tart = require('tart-stepping');
var marshal = require('../index.js');
var stepping = tart.stepping();
var sponsor = stepping.sponsor;
var network = marshal.router();
var domain0 = network.domain('ocap:zero');
var domain1 = network.domain('ocap:one');
var pingBeh = function pingBeh(message) {
if (message.value === undefined) {
var pong = message.pong;
pong({ ping:this.self, pong:pong, value:"pinging" });
} else {
console.log('ping', message.value);
console.log('(ping === message.ping)', (ping === message.ping));
}
};
var pongBeh = function pongBeh(message) {
var ping = message.ping;
ping({ ping:ping, pong:this.self, value:"ponging" });
console.log('pong', message.value);
};
var ping = sponsor(pingBeh);
var pong = sponsor(pongBeh);
var pingToken = domain0.localToRemote(ping);
var pingProxy = domain1.remoteToLocal(pingToken);
pingProxy({ pong: pong }); // send message between domains
stepping.eventLoop({
log: function(effect) {
console.dir(effect);
}
});
npm test
npm run all-examples
Public API
- marshal.router([defaultRoute])
- router.domain([name])
- marshal.domain([name], [transport])
- domain.decode(json)
- domain.encode(message)
- domain.localToRemote(actor)
- domain.remoteToLocal(token)
- domain.bindLocal(token, actor)
- domain.receptionist(message)
- marshal.randomBytes(size[, callback])
defaultRoute
: Functionfunction (message) {}
(default throws) Handle messages to unrecognized domains.- Return: Object
router
capabilities.defaultRoute
: Function As specified on creation.transport
: Functionfunction (message) {}
Route messages (in transport format) to remote domains.domain
: Functionfunction (name) {}
Create a domain registered to use this router as transport.routingTable
: Object (default{}
) Mapping from domains to transports.
Creates a new router and returns a control object. The protocol for all transports consists of messages with the format { address:<token>, message:<json> }
(called transport format). The router.transport
function uses router.routingTable
to look up routes (transports) based on the domain portion of the address
.
name
: String URI (without fragment) for this domain. (default auto-generated)- Return: Object
domain
capabilities. Same asmarshal.domain()
Creates a new domain and returns capabilities to make tokens and proxies. This is a convenience function that uses marshal.domain()
, providing router.transport
as the transport. It also registers the domain.receptionist
under router.routingTable[name]
.
name
: String URI (without fragment) for this domain. (default auto-generated)transport
: Functionfunction (message) {}
(default throws) Route messages (in transport format) to remote domains.- Return: Object
domain
capabilities.name
: String As specified (or generated) on creation.transport
: Function As specified on creation.localToRemote
: Functionfunction (actor) {}
Make a token from a local actor reference.remoteToLocal
: Functionfunction (token) {}
Make a proxy from remote actor token.bindLocal
: Functionfunction (token, actor) {}
Associate a token with a local actor reference.decode
: Functionfunction (json) {}
Decode a message for use within thedomain
.encode
: Functionfunction (message) {}
Encode a message from within thedomain
.receptionist
: Functionfunction (message) {}
Decode a message (in transport format) and deliver it to an actor local to the domain.
Creates a new domain and returns capabilities to make tokens and proxies. Also provides a receptionist, used by transports to deliver remote messages.
json
: JSON JSON encoded message.- Return: Any Message decoded for use within the
domain
.
Decodes json
, replacing any capability references using domain.remoteToLocal(token).
message
: Any Message from within thedomain
to be encoded for transport.- Return: JSON Encoded
message
as JSON.
Encodes the message
, replacing any functions (actor references) using domain.localToRemote(actor).
actor
: Functionfunction (message) {}
local actor reference.- Return: String remote actor reference token.
Return a token representing the local actor
. Multiple request with the same actor
always produce the same token.
token
: String remote actor reference token.- Return: Function
function (message) {}
proxy capability.
Return a proxy that will forward messages to the remote actor represented by the token
. Multiple request with the same token
always return the same proxy.
token
: String remote actor reference token.actor
: Functionfunction (message) {}
local actor reference.
Associate a token
with a local actor
. Future calls to domain.localToRemote
with this actor
always return this token
.
message
: Object Asynchronous message to domain receptionist actor.address
: String destination actor reference token.json
: String marshal-encoded message content.
Decodes json
using domain.decode(json) and sends the result as a message to the actor designated by decoding address
using domain.remoteToLocal(token). The original message
encoding is called transport format.
size
: Integer Number of bytes to generate.callback
: Function (Default: undefined)function (error, buffer) {}
Callback to invoke once bytes are generated.
Exposed to allow for replacement in case of need for deterministic testing.