Source: node/ChildReferenceProvider.js

import ChildProcess from 'child_process';
import beof from 'beof';
import Address from '../Address';
import RefState from '../RefState';
import Concern from '../Concern';
import ChildStateProvider from './ChildStateProvider';
import ChildReference from './ChildReference';
import SpawnChildProcessError from './SpawnChildProcessError';
import StateProvider from '../StateProvider';

/**
 * ChildReferenceProvider provides a Reference for a Concern
 * running on a child process.
 * @implements {ReferenceProvider}
 */
class ChildReferenceProvider {

    constructor() {

        this._cache = {};
        this._list = {};

    }

    /**
     * getProcessList returns a map of child process
     * created by this provider.
     * @return {object}
     */
    getProcessList() {

        return this._list;

    }

    select(path, context) {

        var addr = Address.fromString(path);
        var concern = new Concern();
        var child;
        var provider;

        if (this._cache.hasOwnProperty(path))
            return this._cache[path];

        //@todo move to validator class
        if (typeof addr.uri.hash !== 'string')
            throw new ReferenceError('A child process uri must have a path and hash part!');

        if (this._list.hasOwnProperty(addr.uri.path)) {

            child = this._list[addr.uri.path];

        } else {

            try {

                child = ChildProcess.fork(addr.uri.path);
                this._list[addr.uri.path] = child;

            } catch (e) {

                context.publish(new SpawnChildProcessError(e));

                return new Reference(new RefState.UnknownState(
                    path, concern, context, new StateProvider()));

            }
        }

        provider = new ChildStateProvider(path, addr.uri.hash.substring(1), child);

        return this._cache[path] = new ChildReference(
            provider.provide(RefState.ACTIVE_STATE, concern, context),
            path, addr.uri.hash.substring(1), concern, context, provider, child);

    }

    reselect(path, context) {

        this._cache[path] = null;
        return this.select(path, context);

    }

}

export default ChildReferenceProvider