Reflection/Inspection
Before a protocol can be executed, it must be examined to learn what input it needs (keys, names, IP addresses), and which results it yields (if any).
Obol scripts use the metacommands [input] and [returns] to specify their input requirements and return values. All input requirements must be satisfied before execution proceeds. Applications can access the set of unset input requirements, and the set of script-set return values at any time. There is a simple event-notification mechanism allowing applications to be notified (or they can poll) of state changes, such as a new input requirement, results becoming available, or that an error has occurred. Listings One and Two show how this mechanism is used by client and server applications, respectively.
import lang.API; import lang.Runtime; import lang.ScriptHandle; import lang.ReturnValue; import lang.ObolException; ... API lobo = Runtime.getInstance(); ScriptHandle script = lobo.getScriptInstance(lobo.loadScript("./server.obol")); script.setSymbol("portNo", 1234); script.startExecution(); try { while(true) { int status = script.waitForStatus(ScriptHandle.STATUS_DONE); if (0 != (status & ScriptHandle.STATUS_RESULT_AVAILABLE)) { System.out.println("Received \"" + script.getSymbol("data").getValue() + "\""); } if (0 != (status & ScriptHandle.STATUS_DONE) { break; } } } catch (ObolException e) { System.err.println(e); }
import lang.API; import lang.Runtime; import lang.ScriptHandle; import lang.ObolException; ... API lobo = Runtime.getInstance(); ScriptHandle script = lobo.getScriptInstance( lobo.loadScript("./client.obol")); script.setSymbol("portNo", 1234); script.startExecution(); try { while(true) { int status = script.waitForStatus(ScriptHandle.STATUS_DONE); if (0 != (status & ScriptHandle.STATUS_DONE) { break; } } } catch (ObolException e) { System.err.println(e); }
Scripts have access to this mechanism, and can invoke other scripts via the [use] metacommand, binding local symbols to input/return symbols defined by the invoked script. Unresolved input requirements are eventually forwarded to the application. Listing Three (available at http://www.ddj.com/code/) is an example of how to examine a script's input requirements; Listing Four (also available at http://www.ddj.com/code/) presents a much quicker way of setting known inputs. The approach is similar for scripts' return values, using the getResultSpecification() and getIntermediateResults() API methods.