IBM Cloud Functions supports a kind of action called a "sequence". Sequence actions are created using a list of existing actions. When the sequence action is invoked, each action in executed in order of the action parameter list. Input parameters are passed to the first action in the sequence. Output from each function in the sequence is passed as the input to the next function and so on. The output from the last action in the sequence is returned as the response result.
{% hint style="info" %} Sequences behave like normal actions, you create, invoke and manage them as actions through the CLI. {% endhint %}
Here's an example of defining an action my_sequence from a sequence of three actions (a, b, and c):
ibmcloud fn action create my_sequence --sequence a,b,c{% hint style="warning" %} The example above is merely an example of the syntax used to create an action sequence and should not be run. {% endhint %}
Using a sequence can remove the need to manually invoke actions and sit idle waiting for a response. In the example above, a sequence would be created for each serverless function in the application, combing the action doing the authentication followed by the actual request processing action.
Let's look at an example of using sequences.
- Create the file (
funcs.js) with the following contents:
function split(params) {
var text = params.text || ""
var words = text.split(' ')
return { words: words }
}
function reverse(params) {
var words = params.words || []
var reversed = words.map(word => word.split("").reverse().join(""))
return { words: reversed }
}
function join(params) {
var words = params.words || []
var text = words.join(' ')
return { text: text }
}- Create the following three actions:
ibmcloud fn action create split funcs.js --main splitibmcloud fn action create reverse funcs.js --main reverseibmcloud fn action create join funcs.js --main join- Test each action to verify it is working.
The function split takes the single string hello world and splits it into a JSON map of the individual strings using the space character as the delimiter.
ibmcloud fn action invoke split --result --param text "Hello world"{
"words": [
"Hello",
"world"
]
}The function reverse takes a JSON array of strings and reverses the characters in each.
ibmcloud fn action invoke reverse --result --param words '["hello", "world"]'{
"words": [
"olleh",
"dlrow"
]
}The function join takes the JSON array of strings and concatenates them back into a space-delimited string.
ibmcloud fn action invoke join --result --param words '["hello", "world"]'{
"text": "hello world"
}- Create the following action sequence.
ibmcloud fn action create reverse_words --sequence split,reverse,join- Test out the action sequence.
ibmcloud fn action invoke reverse_words --result --param text "hello world"{
"text": "olleh dlrow"
}{% hint style="success" %} 🎉As you can see, using sequences is a great way to develop re-usable action components that can be joined together into "high-order" actions to create serverless applications. 🎉 {% endhint %}
What if you want to stop processing functions in a sequence? This might be due to an application error or because the pre-conditions to continue processing have not been met. In the authentication example above, we only want to proceed if the authentication check passes.
If any action within the sequences returns an error, the platform returns immediately. The action error is returned as the response. No further actions within the sequence will be invoked.
Let's look at how this work...
- Add the following functions to the file
funcs.js:
function fail (params) {
if (params.fail) {
throw new Error("stopping sequence and returning.")
}
return params
}
function end (params) {
return { message: "sequence finished." }
}- Create the following three actions:
ibmcloud fn action create fail funcs.js --main failibmcloud fn action create end funcs.js --main endibmcloud fn action create example --sequence fail,end- Test out the action sequence without the
failparameter:
ibmcloud fn action invoke example -r{
"message": "sequence finished."
}-
Test out the action sequence with the
failparameter set totrue:ibmcloud fn action invoke example -r -p fail true{ "error": "An error has occurred: Error: stopping sequence and returning." }
We can even find out more about the failed action.
- List the last few activations
ibmcloud fn activation list -l 2Activation ID Kind Start Duration Status Entity
1b8144afde1244738144afde12c4732a nodejs:10 cold 46ms developer error fail:0.0.1
eab8ed35f2fc4236b8ed35f2fc423657 sequence warm 96ms developer error example:0.0.1- get the details of the failed action (i.e.,
fail)
ibmcloud fn activation get 1b8144afde1244738144afde12c4732aok: got activation 1b8144afde1244738144afde12c4732a
{
...
"logs": [
"20xx-11-19T16:11:46.132237Z stderr: Error: stopping sequence and returning.",
"20xx-11-19T16:11:46.132244Z stderr: at NodeActionRunner.fail [as userScriptMain] (eval at initializeActionHandler (/nodejsAction/runner.js:57:23), <anonymous>:21:13)",
"20xx-11-19T16:11:46.132248Z stderr: at Promise (/nodejsAction/runner.js:73:35)",
...
],
...As you can, the sequence was stopped at the failed action fail.
{% hint style="success" %} 🎉 Congratulations for getting this far! The use of Sequences is an "advanced" technique that can bring Serverless applications to life. Now let's explore how we might manage groups of like Actions within Packages further enabling composition and reuse…** 🎉 {% endhint %}