Skip to content
This repository has been archived by the owner on May 22, 2020. It is now read-only.

Runtime Mesh

Ricardo De Peña edited this page Jun 2, 2017 · 6 revisions

Upon launching, OpenFin processes will join or initiate a full duplex connection to a mesh network of peer runtimes.

The mesh will provide location transparency and migration transparency by means of a self healing distributed hash table.

Any given runtime will be connected to N peers and local Map EM of know and unique entity keys (Identity for the most part) and their location on the network, in the case of delivery failure the map will try to self heal and eventually fail if this entity is no longer present in the network (Application or connection close).

Joining the runtime Mesh will involve leveraging the existing Port Discovery protocol with small changes to allow peer runtimes to subscribe to Port Discovery Messages.

Example of Runtime B joining an existing Runtime Mesh:

Runtime Action
Runtime B Publishes port discovery information
Runtime A Uses port discovery message to connect directly to Runtime B
Runtime A Adds Runtime B to its ResolveK(K) Map
Runtime A Publishes port discovery information
Runtime B Uses port discovery message to connect directly to Runtime A
Runtime B Adds Runtime A to its ResolveK(K) Map

API Messages will be routed to the correct Runtime, internally the remote API will be utilized through a facade, allowing calls to remote and local objects to be transparent. Example of an API message routed in a Runtime Mesh:

Runtime Action
Runtime A Gets API call X for entityKey
Runtime A ResolveK(entityKey)
Runtime B Respond with Runtime B Address
Runtime A Creates route map for entityKey
Runtime A Routes API call x to Runtime B
Runtime B Executes x on entityKey
Runtime A Routes response to original requester

Code

The Runtime Mesh is composed of a few moving parts:

  • Runtime P2P: Is responsible of maintaining the Entity Map. Abstracting connection and Identity resolution.

Exposes the ConnectionManager class:

export interface PeerRuntime {
    portInfo: PortInfo;
    fin: Fin;
    isDisconnected: boolean;
    identity: Identity;
}

export interface IdentityAddress {
    runtime: PeerRuntime;
    runtimeKey: string;
    identity: Identity;
}

export interface PortInfo {
    version: any;
    sslPort: number;
    port: number;
    requestedVersion?: string;
    securityRealm?: string;
    runtimeInformationChannel?: string;
}

export class ConnectionManager extends EventEmitter {

    connectToRuntime(uuid: string, portInfo: PortInfo): Promise<PeerRuntime>;
    get connections(): Array<PeerRuntime>;
    resolveIdentity(identity: Identity) : Promise<IdentityAddress>;
}
  • Node Adapter: Is utilized by the Runtime P2P Module to marshal API messages from Runtime to Runtime.

Uses the Execute remote API call to forward API messages

export class System {
    public executeOnRemote(requestingIdentity: Identity, data: any): Promise<any>;
}
  • Port Discovery: Is used by the Runtime Core to discover other Runtimes and announce itself to listening Runtime.

Currently wm_copydata based, subscriptions are done in core/index.js

//We subscribe to all port discovery messages from other runtimes.
portDiscovery.on('runtime/launched', (portInfo) => {
    connectionManager.connectToRuntime(`${myPortInfo.version}:${myPortInfo.port}`, portInfo)
    .then((runtimePeer) => {
         portDiscovery.broadcast(myPortInfo);
    });

});

API Middleware as defined by hadoukenIO/core/mesh_middleware.ts

//the following preprocessors are registered

function registerMiddleware (requestHandler: RequestHandler<MessagePackage>): void {
    requestHandler.addPreProcessor(subscriberEventMiddleware);
    requestHandler.addPreProcessor(publishMiddleware);
    requestHandler.addPreProcessor(sendMessageMiddleware);
    requestHandler.addPreProcessor(ferryActionMiddleware);
}