JavaScript RPC Runtime

Description

The Server Process hosts a JavaScript runtime (currently a Mozilla Rhino implementation) capable of loading scripts and exercising HUGIN and script objects.  This can be remotely controlled from the user web application running in the browser.

Using the remote procedure call feature, we can move the parts of the user code that performs many HUGIN API function calls from running in the browser to run locally in the Server Process.  Thus mitigating the HTTP communication overhead induced by having to perform many HUGIN API calls from browser script code.

Experimental Feature

The remote procedure call feature is experimental and must be explicitly enabled on the server, see the options section on the About page.

A note about garbage collection

All HUGIN objects (Domains and Nodes etc.) that at some point have visited the scope of the remote script object will be garbage collected when the remote script object itself is deleted or garbage collected.

A note about passing arguments to RPC

The only supported types are the basic JavaScript primitives (numbers, strings, arrays, and object literals) and HUGIN objects (Domains, Nodes, etc.).  At each function invocation, the arguments and result communicated between browser-side and server-side JavaScript runtimes, except for HUGIN objects, will be copies of the corresponding primitive JavaScript data structures.

Method stubs

The web application running in the browser-side JavaScript runtime can communicate with the script object living in the server-side JavaScript runtime.  This communication is done using a proxy object (a RemoteObject) in the browser-side runtime which has a number of stubs that mirror the methods exposed by the server-side remote object.  The stubs on the RemoteObject are dynamically discovered and exposed.  So if the server-side remote object provides a method ‘.giveMeFive()’, then the browser-side RemoteObject will be augmented with a similar method stub ‘.giveMeFive()’.  Thus if we invoke ‘.giveMeFive()’ on the RemoteObject then in turn the server-side ‘.giveMeFive()’ is invoked, and results are transparently communicated back as the return value for the RemoteObject ‘.giveMeFuve()’ stub.

Loading a server-side script and constructing remote object

In this example we have two script files, one which will be evaluated in the server-side JavaScript runtime and another evaluated in the browser-side JavaScript runtime.

  • load server-side script
  • construct remote object in server-side JavaScript runtime
  • get a RemoteObject proxy object for communicating with the server-side remote object
//file: serverSideScript.js
function MyObject(constructorArg) {
  this.giveMeFive = function() {
    return 5;
  };

  this.giveMeConstructorArg = function() {
    return constructorArg;
  };
}

//file: browserSideScript.js
//...
var hapi; // a HAPI instance
var rpc = new HuginRPC(hapi);

//create the RemoteObject proxy object
var remoteObject = rpc.getNewRemoteScriptObject("/path/to/serverSideScript.js", "MyObject", "an argument string");
//the serverSideScript.js script is loaded server-side, and 'new MyObject("an argument string")' is called

Remote procedure call (traditional synchronous blocking fashion)

We can now invoke a method on a remote script object using the RemoteObject proxy object just as if it was a plain object in the browser-side JavaScript runtime.

//file: browserSideScript.js
//...
alert(remoteObject.giveMeFive()); //prints '5'
alert(remoteObject.giveMeConstructorArg()); //prints 'an argument string'

Remote procedure call (asynchronous non-blocking fashion)

Methods on the remote script object can also be invoked asynchronously, this means that invoking the stub returns immediately and a callback function is used to handle the result when the remote script object function returns.

//file: browserSideScript.js
//...

//this is our callback function
function alertCallback(result) {
  var remoteFunctionReturned = result.invocationResult();
  alert(remoteFunctionReturned);
}

//dispatch the function calls
remoteObject.Async(alertCallback).giveMeFive();
remoteObject.Async(alertCallback).giveMeConstructorArg();
Summary
JavaScript RPC RuntimeThe Server Process hosts a JavaScript runtime (currently a Mozilla Rhino implementation) capable of loading scripts and exercising HUGIN and script objects.
HuginRPCThe HuginRPC is the main entry point for spawning remote script objects in the Server Process.
Functions
HuginRPCInitialize a new HuginRPC instance.
getNewRemoteScriptObjectRemotely load a JavaScript file, invoke a JavaScript object constructor, and return a RemoteObject reference to the remotely constructed object.
RemoteObjectA RemoteObject is a reference to a specific script object living in the Server Process.
Functions
deleteObjectDeletes this RemoteObject (as well as all HUGIN objects in the RemoteObjects scope).
reflectMethodStubsInspects the set of functions attached to the server-side object and automagically creates corresponding method stubs for discovered functions on this RemoteObject.
AsyncHook for asynchronously invoking a function on the remote script object.

HuginRPC

The HuginRPC is the main entry point for spawning remote script objects in the Server Process.

Summary
Functions
HuginRPCInitialize a new HuginRPC instance.
getNewRemoteScriptObjectRemotely load a JavaScript file, invoke a JavaScript object constructor, and return a RemoteObject reference to the remotely constructed object.

Functions

HuginRPC

function HuginRPC(hapi)

Initialize a new HuginRPC instance.  The HuginRPC instance can spawn script objects in the Server Process connected to the HAPI constructor argument.

Parameters

hapia HAPI instance

Returns

A HuginRPC instance

getNewRemoteScriptObject

this.getNewRemoteScriptObject = function getNewRemoteScriptObject(
    scriptUrl,
   constructorName //,
    arg0,
    arg1,
    ...,
    argN
)

Remotely load a JavaScript file, invoke a JavaScript object constructor, and return a RemoteObject reference to the remotely constructed object.

This results in a two-stage process taking place in the Server Process

  • 1) parse and evaluate the JavaScript code
  • 2) call ‘new MyConstructor (args...) - where ‘MyConstructor’ is the string passed in constructorName, and args... is the arguments passed.

The RemoteObject returned is a reference to the remote object constructed by the ‘new’ call.

Parameters

scriptUrlpath to the script to load.  The path can be a URL relative to the current web page location or an absolute URL.
constructorNamethe name of the remote script object constructor.
arg0, arg1, ..., argNthe arguments passed to the remote script object constructor.

Returns

a RemoteObject object

Example

var rpc; //a HuginRPC instance
var remoteObject = rpc.getNewRemoteScriptObject("some/path/to/a/script.js", "MyObject", "");

RemoteObject

A RemoteObject is a reference to a specific script object living in the Server Process.  The RemoteObject has method stubs facilitating remote procedure calls to the server-side remote scripting object.  The exact method stubs are determined at remote object construction time by automatic reflecting the function properties of the remote scripting object, or at some later point using RemoteObject.reflectMethodStubs().

For instructions on how to perform remote procedure calls, refer to the description text found under JavaScript RPC Runtime.

Summary
Functions
deleteObjectDeletes this RemoteObject (as well as all HUGIN objects in the RemoteObjects scope).
reflectMethodStubsInspects the set of functions attached to the server-side object and automagically creates corresponding method stubs for discovered functions on this RemoteObject.
AsyncHook for asynchronously invoking a function on the remote script object.

Functions

deleteObject

this.deleteObject = function deleteObject()

Deletes this RemoteObject (as well as all HUGIN objects in the RemoteObjects scope).

Returns

void

Example

r.deleteObject();

reflectMethodStubs

this.reflectMethodStubs = function reflectMethodStubs()

Inspects the set of functions attached to the server-side object and automagically creates corresponding method stubs for discovered functions on this RemoteObject.  Normally one does not need to explicitly invoke this function.  But in cases where the remote script object populates additional methods after its constructor has run, this function must be called to discover new methods and create stubs before they can be invoked over RPC.

Returns

list of method names discovered

Example

  • reflect and install stubs on the RemoteObject object ‘r’:
r.reflectMethodStubs();

Async

this.Async = function Async(callback)

Hook for asynchronously invoking a function on the remote script object.

This is a three-stage process

  • 1) register callback function: call RemoteObject.Async() to register a callback.
  • 2) dispatch function call: the call to RemoteObject.Async() returns an object populated with function stubs and calling one of those dispatches the remote procedure call.
  • 3) handle result: When the remote function call has completed, the callback function is invoked with a result object passed as parameter.  To get the result of the function call within the callback, invoke result.invocationResult().  If the remote function threw an error, then the result.invocationResult() will throw an error.

Parameters

callbacka callback function(result), to be invoked when the remote script object function returns.

Returns

an object containing asynchronous function stubs.

Example

  • create a remote script object.
  • asynchronously invoke the function ‘performComputation’ on the remote script object.
var rpc; //a HuginRPC instance
var remoteObject = rpc.getNewRemoteScriptObject("some/path/to/a/script.js", "MyObject", "");

function myCallback(result) {
  //handle when function call completes
  try {
    var computedValue = result.invocationResult();
    //do stuff
    //...
  } catch (error) {
    //the remote function may have thrown an error, handle this
    alert("An error occured: " + e.name + "\n" + e.message);
  }
}

remoteObject.Async(myCallback).performComputation();
The HUGIN decision engine lives in the server process.
function HuginRPC(hapi)
Initialize a new HuginRPC instance.
this.getNewRemoteScriptObject = function getNewRemoteScriptObject(
    scriptUrl,
   constructorName //,
    arg0,
    arg1,
    ...,
    argN
)
Remotely load a JavaScript file, invoke a JavaScript object constructor, and return a RemoteObject reference to the remotely constructed object.
A RemoteObject is a reference to a specific script object living in the Server Process.
this.deleteObject = function deleteObject()
Deletes this RemoteObject (as well as all HUGIN objects in the RemoteObjects scope).
this.reflectMethodStubs = function reflectMethodStubs()
Inspects the set of functions attached to the server-side object and automagically creates corresponding method stubs for discovered functions on this RemoteObject.
this.Async = function Async(callback)
Hook for asynchronously invoking a function on the remote script object.
The HUGIN Web Service API is the HUGIN decision engine turned into a RESTful web service.
Instances of the Domain class represent Bayesian networks and LIMIDs in which you can propagate evidence and calculate updated beliefs and expected utilities.
Nodes are one of the fundamental objects used in the construction of Bayesian networks and LIMIDs.
The HAPI class is a container for all functionality in the JavaScript for HUGIN Web Service API.
The Server Process hosts a JavaScript runtime (currently a Mozilla Rhino implementation) capable of loading scripts and exercising HUGIN and script objects.
Close