Reflex Suspension - RapturePlatform/Rapture GitHub Wiki
Suspension and Coordination
Reflex can be hosted in an environment that can support suspension and eventual resumption. On the one hand, suspension is useful to simply pause the running script for a set amount of time in order to wait for some external activity to take place. Upon resumption from suspension the script continues from where it was suspended. Another use case involves a script actively waiting (coordinating) with the activity of another script -- when the target script is completed the suspending (waiting) script automatically resumes.
In the Rapture context the suspension involves freezing the context of the script -- its variables, the calling parameters, the modules loaded and the exact point of suspension -- and then either placing the suspended script onto the Rapture pipeline for resumption as soon as possible or making a scheduled task entry for resumption at a future point in time. The important aspect of this suspension is that the resumption can take place on a different Rapture server to that which originally ran the script, and in fact due to the virtual nature of Rapture servers the original server may no longer exist.
Suspension Functions
suspend
The suspend
function takes one parameter - a number that represents a desired amount of time to suspend. The actual amount of time suspended will vary depending on the container that the script is running on. To a script writer it should be considered as a pause in the execution of a script. A script can be suspended any number of times.
// Suspend example
i = 5;
suspend(10); // Suspend for approximately 10 seconds
println("I is " + i);
@call
The @call
function makes an asynchronous request to execute a script that is passed as the first parameter to the function. The second parameter to this function forms the parameters to the invoked script. The request is placed onto the Rapture pipeline for execution, and a handle to that request is returned from this function. This handle (which is in fact a string) can be used in the @wait
and @status
functions described below.
program = "println('Hello world')";
handle = @call(program, {});
In the above example we pass in an empty parameter set {}
to the script being invoked.
The @call
function internally uses the connect to the Rapture API environment for execution -- the script will be executed on that environment which is not necessarily the same environment that is running the script making the @call
invocation.
callScript
The @callScript
function is very similar to the @call
function above, except that it refers to a script that is already hosted on a Rapture server. The single script parameter of the @call
function is replaced by a parameter to reference this script -- the Rapture URI of the script. As with @call
, this function returns a handle that can be used in @wait
and @status
.
handle = @callScript("//test/myScript", {});
@status
The @status
function returns a map containing details of the current execution of a script that was originally scheduled through an @call
or @callScript
invocation.
program = "println('Hello world');";
handle = @call(program, {});
println(@status(handle));
A typical output from the above program is reproduced below (assuming the script was actually executed in the time between the invocation and the status call).
{
state=COMPLETED,
taskId=2abd8d30-f7ea-4956-908c-e04737d64c0e,
relatedTaskId=,
creationTime=1354632237825,
startExecutionTime=1354632237827,
endExecutionTime=1354632237829,
suspensionCount=0,
output=["Hello world"]
}
The resultant status document has an important state
field that can have the values of SUBMITTED, RUNNING, COMPLETED, FAILED or SUSPENDED. The taskId corresponds to the handle of the call, the time fields are set dependent on the execution of the task and the suspensionCount field indicates the number of times this task has been suspended. Finally the output field is a list of strings that contain any output from any print or println statements in the executed script.
@wait
The @wait
function waits for an array of handles to be either COMPLETED or FAILED. It can be used to suspend the current script until any invoked @call
or @callScript
scripts have completely finished executing. Like suspend
it takes a parameter that indicates the amount of time it should expect to wait between suspensions before waking up to check the status of the called scripts. An example is reproduced below:
handles = [];
for i = 1 to 50 do
program = "println('hello from " + i + " ');";
handle = @call(program, {});
handles = handles + handle;
end
@wait(10, handles);
for h in handles do
println(@status(h));
end
In this example the master script invokes 50 asynchronous scripts, each with a different output. Once they are all completed it enumerates through the executed scripts printing their eventual status.