Beispiel #1
0
test['ping/pong example with multiple sponsors'] = function (test) {
    test.expect(4);
    var dom0Sponsor = tart.minimal();
    var dom1Sponsor = tart.minimal();

    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;
            test.notStrictEqual(_pong, pong);
            _pong({ ping:this.self, pong:_pong, value:'pinging' });
        } else {
            test.equal(message.value, 'ponging');
            test.strictEqual(message.ping, ping);
            test.done();
        }
    };

    var pongBeh = function pongBeh(message) {
        var ping = message.ping;
        ping({ ping:ping, pong:this.self, value:'ponging' });
        test.equal(message.value, 'pinging');
    };

    var ping = dom0Sponsor(pingBeh);
    var pong = dom1Sponsor(pongBeh);

    var pingToken = domain0.localToRemote(ping);
    var pingProxy = domain1.remoteToLocal(pingToken);

    pingProxy({ pong: pong });  // send message between domains
};
Beispiel #2
0
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

*/
"use strict";

//var log = console.log;
var log = function () {};

var tart = require('tart');
var sponsor = tart.minimal({
    fail: function (e) {
        console.log('ERROR!', e);
    }
});

var PEG = require('../PEG.js');
var input = require('../input.js');

var pf = PEG.factory(sponsor);
var ns = pf.namespace(log);

ns.defaultTransform = ((name, value) => value);

/*
Assign <- (Name "=")* Expr
*/
ns.define('Assign',
Beispiel #3
0
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

*/
"use strict";

var marshal = require('../index.js');
var tart = require('tart');
var transport = require('tart-transport-udp');

var sponsor = tart.minimal();

var send = sponsor(transport.sendBeh);

var domain0 = marshal.domain('udp://localhost:10000/', send);
var domain1 = marshal.domain('udp://localhost:10001/', send);

var pingBeh = function pingBeh(message) {
    console.dir(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);
        closeDomain0();
Beispiel #4
0
module.exports.checkpoint = function checkpoint(options) {
    options = options || {};
    
    options.dispatchEvent = options.dispatchEvent || function dispatchEvent(callback) {
        // Checkpoint.
        options.saveCheckpoint(function (error) {
            if (error) { return callback(error); }
            // Dequeue event to dispatch.
            var event = options.dequeueEvent();
            // If queue is empty, dispatch is done.
            if (!event) { return callback(false); }
            // Process event.
            options.processEvent(event);
            // Checkpoint.
            options.saveCheckpoint(function (error) {
                if (error) { return callback(error); }
                // Schedule next dispatch.
                options.scheduleDispatch();
                // Dispatch is done.
                return callback(false);
            });
        });
    };

    options.saveCheckpoint = options.saveCheckpoint || function saveCheckpoint(callback) {
        // If effect is empty, checkpoint is done.
        if (options.effectIsEmpty(options.effect)) { return callback(false); }
        // Write effect to log.
        options.logEffect(function (error) {
            if (error) { return callback(error); }
            // If effect is an error, clear effect, checkpoint is done.
            if (options.effectIsError(options.effect)) {
                options.effect = options.newEffect();
                return callback(false);
            }
            // Add messages sent, if any, to event queue.
            options.enqueueEvents();
            // Persist global state
            options.persistState(function (error) {
                if (error) { return callback(error); }
                // Initialize empty effect.
                options.effect = options.newEffect();
                // Checkpoint is done.
                callback(false);
            });
        });
    };

    options.logEffect = options.logEffect || function logEffect(callback) {
        var json = domain.encode(options.effect);
        console.log('logEffect:', json);
        setImmediate(function () {
            callback(false);
        });
    };

    options.persistState = options.persistState || function persistState(callback) {
        console.log('persistState effect:', options.effect);
        console.log('persistState events:', options.events);
        setImmediate(function () {
            callback(false);
        });
    };

    options.newEffect = options.newEffect || function newEffect() {
        return {
            created: [],
            sent: []
        };
    };

    options.effectIsEmpty = options.effectIsEmpty || function effectIsEmpty(effect) {
        if (effect.event
        ||  effect.exception
        ||  (effect.sent.length > 0)
        ||  (effect.created.length > 0)) {
            return false;
        }
        return true;
    };

    options.effectIsError = options.effectIsError || function effectIsError(effect) {
        if (effect.exception) {
            return true;
        }
        return false;
    };

    options.enqueueEvents = options.enqueueEvents || function enqueueEvents() {
        options.events.push(options.effect.sent.slice());  // clone event batch
    };

    options.dequeueEvent = options.dequeueEvent || function dequeueEvent() {
        while (options.events.length > 0) {
            var batch = options.events[0];
            if (batch.length > 0) {
                return batch.shift();  // return next event
            }
            options.events.shift();
        }
        return false;
    };
    
    options.compileBehavior = options.compileBehavior || function compileBehavior(source) {
        return eval('(' + source + ')');  // must produce a Function
    };

    options.processEvent = options.processEvent || function processEvent(event) {
        console.log('processEvent event:', event);
        options.effect.event = event;
        try {
            options.effect.behavior = event.context.behavior;
            event.context.behavior = options.compileBehavior(options.effect.behavior);
            event.context.behavior(event.message);  // execute actor behavior
            options.effect.became = event.context.behavior.toString();
            event.context.behavior = options.effect.became;
        } catch (exception) {
            options.effect.exception = exception;
        }
        console.log('processEvent effect:', options.effect);
    }

    options.events = [];  // queue of pending events (in effect batches)
    
    options.effect = options.newEffect();  // initialize empty effect

    options.inDispatch = false;
    options.scheduleDispatch = options.scheduleDispatch || function scheduleDispatch() {
        setImmediate(function () {
            console.log('scheduleDispatch:', options.inDispatch);
            if (options.inDispatch) {
                options.errorHandler(new Error('DISPATCH RE-ENTRY'));
            }
            options.inDispatch = true;
            options.dispatchEvent(function (error) {
                options.inDispatch = false;
                options.errorHandler(error);
            });
        });
    };

    options.errorHandler = options.errorHandler || function errorHandler(error) {
        if (error) {
            console.log('FAIL!', error);
        }
    };

    options.scheduleDispatch();  // prime the pump...
    
    var name = options.name || 'checkpoint';
    var sponsor = options.sponsor || tart.minimal();
    var router = marshal.router(sponsor);
    var domain = router.domain(name);
    var receptionist = domain.receptionist;
    domain.receptionist = function checkpointReceptionist(message) {
        console.log('checkpointReceptionist:', message);
        receptionist(message);  // delegate to original receptionist
        options.scheduleDispatch();  // trigger checkpoint scheduler
    };
    var transport = domain.transport;
    domain.transport = function checkpointTransport(message) {
        console.log('checkpointTransport:', message);
        transport(message);  // delegate to original transport
    };

    options.checkpoint = {
        router: router,
        domain: domain,
        sponsor: function create(behavior, state) {
            state = state || {};
            var actor = function send(message) {
                var event = {
                    message: message,
                    context: context
                };
                options.effect.sent.push(event);
            };
            var context = {
                self: actor,
                state: state,
                behavior: behavior.toString(),
                sponsor: create
            };
            options.effect.created.push(context);
            return actor;
        }
    };

    return options.checkpoint;
};