Chaining Scripts
Introduction
It is possible to “chain” from one Lua script to another. Both scripts must be executed by the same service, and hence the same service loader. Each script load in the chain may use the same script key, or different script keys.
A typical use of script-chaining might be:
- A number portability/translation service script, followed by
- A service script whose flow depends on the translated number.
It is possible to chain three or more scripts in a sequence. To avoid unintended infinite loops of service chaining, there is a maximum chain count limit defined on the LogicApp configuration.
The chain method is accessed via the “n2.n2svcd” module:
local n2svcd = require "n2.n2svcd"
Note that the “script_key” for the first script is determined by the service loader, using a mechanism which is specific to the individual service loader.
One common approach is a static “trigger” list configured in the service loaders <config>
block, although it can use any mechanism such as a dedicated XML file, or a database,
or an external server lookup.
But when chaining to a second or subsequent script, this “trigger” or other lookup
process is skipped, since the Lua script performing the handover is explicitly
specifying the “script_key” (possibly nil
for a two-phase loader) for the new script.
Calling Sequence
To chain to another Lua script, the originating script will:
- Call
n2svcd.chain
to specify the new script key, then - Call
return
from the top-level and pass the initial args for the next script.
The args returned by the first script will be the “initial_args” passed in as the first parameter to the main funcion of the next script.
Note that it is not possible for the source (calling) script to set the second “extra_args” parameter of the destination (called) script. These “extra_args” are determined exclusively by the service loader.
Script Continuity
Any Lua global variables are lost, since the original Lua context is freed (and may be subsequently re-used), and a new Lua context is created (or re-used).
But outside of the Lua layer, continuity is generally retained as two scripts will reside in the single common “Script Instance”, meaning that:
- EDRs generated by the logic app will share the same “Instance IDX”.
- In-memory debug tracing will be contiguous.
- TCAP Transactions will remain open across the scripts.
- Other session context and states (e.g. SCP or SIP call control) will remain.
The script designer must of course ensure that the second scripts are built so as to respect any limitations on session state. For example if the first script has invoked SCP “Release Call”, then any attempt by the second script to perform e.g. voice interaction will naturally fail.
.chain [Asynchronous]
This method specifies the script key for the script which will be run when the first
script performs a top-level return
from its main function.
The chain
method takes the following parameters.
Parameter | Type | Description |
---|---|---|
script_key
|
String |
The script key which determine the script to which we will chain. (Default = no script key, use a two-phase loading sequence). |
Some loaders can support an undefined script key. Such loaders are called two-phase loaders, as they typically perform one database lookup to determine the script key, and a second database lookup to load the actual Lua script for that key.
Example (a depth-one chain for a REST service):
local n2svcd = require "n2.n2svcd"
local http = require "n2.http"
local rest = ...
if (CHAIN_COUNT == 0) then
print ("Calling Script")
rest.my_value = "FOO"
-- Chain to ourself.
n2svcd.chain (SCRIPT_KEY)
return rest
end
-- Second call. Chain count is now == 1.
print ("Called Script " .. CHAIN_COUNT)
-- Return a success with our encoded JSON data.
return { code = 200, content_type = "application/json", content = n2svcd.json_encode ({ field = my_value.FOO }) };
The chain
method returns nil
.