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:

  1. A number portability/translation service script, followed by
  2. 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:

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:

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.