Giter Club home page Giter Club logo

openwhisk-composer's Introduction

Apache OpenWhisk Composer

Travis License Join Slack

Composer is a new programming model for composing cloud functions built on Apache OpenWhisk. With Composer, developers can build even more serverless applications including using it for IoT, with workflow orchestration, conversation services, and devops automation, to name a few examples.

Composer synthesizes OpenWhisk conductor actions to implement compositions. Compositions have all the attributes and capabilities of an action, e.g., default parameters, limits, blocking invocation, web export.

This repository includes:

Installation

Composer is distributed as Node.js package. To install this package, use the Node Package Manager:

npm install -g openwhisk-composer

We recommend installing the package globally (with -g option) if you intend to use the compose and deploy commands to compile and deploy compositions.

Defining a composition

A composition is typically defined by means of a JavaScript expression as illustrated in samples/demo.js:

const composer = require('openwhisk-composer')

module.exports = composer.if(
    composer.action('authenticate', { action: function ({ password }) { return { value: password === 'abc123' } } }),
    composer.action('success', { action: function () { return { message: 'success' } } }),
    composer.action('failure', { action: function () { return { message: 'failure' } } }))

Compositions compose actions using combinator methods. These methods implement the typical control-flow constructs of an imperative programming language. This example composition composes three actions named authenticate, success, and failure using the composer.if combinator, which implements the usual conditional construct. It takes three actions (or compositions) as parameters. It invokes the first one and, depending on the result of this invocation, invokes either the second or third action.

This composition includes the definitions of the three composed actions. If the actions are defined and deployed elsewhere, the composition code can be shortened to:

composer.if('authenticate', 'success', 'failure')

Deploying a composition

One way to deploy a composition is to use the compose and deploy commands:

compose demo.js > demo.json
deploy demo demo.json -w
ok: created /_/authenticate,/_/success,/_/failure,/_/demo

The compose command compiles the composition code to a portable JSON format. The deploy command deploys the JSON-encoded composition creating an action with the given name. It also deploys the composed actions if definitions are provided for them. The -w option authorizes the deploy command to overwrite existing definitions.

Running a composition

The demo composition may be invoked like any action, for instance using the OpenWhisk CLI:

wsk action invoke demo -p password passw0rd
ok: invoked /_/demo with id 09ca3c7f8b68489c8a3c7f8b68b89cdc

The result of this invocation is the result of the last action in the composition, in this case the failure action since the password in incorrect:

wsk activation result 09ca3c7f8b68489c8a3c7f8b68b89cdc
{
    "message": "failure"
}

Execution traces

This invocation creates a trace, i.e., a series of activation records:

wsk activation list
Datetime            Activation ID                    Kind     Start Duration   Status  Entity
2019-03-15 16:43:22 e6bea73bf75f4eb7bea73bf75fdeb703 nodejs:10 warm  1ms        success guest/demo:0.0.1
2019-03-15 16:43:21 7efb6b7354c3472cbb6b7354c3272c98 nodejs:10 cold  31ms       success guest/failure:0.0.1
2019-03-15 16:43:21 377cd080f0674e9cbcd080f0679e9c1d nodejs:10 warm  2ms        success guest/demo:0.0.1
2019-03-15 16:43:20 5dceeccbdc7a4caf8eeccbdc7a9caf18 nodejs:10 cold  29ms       success guest/authenticate:0.0.1
2019-03-15 16:43:19 66355a1f012d4ea2b55a1f012dcea264 nodejs:10 cold  104ms      success guest/demo:0.0.1
2019-03-15 16:43:19 09ca3c7f8b68489c8a3c7f8b68b89cdc sequence warm  3.144s     success guest/demo:0.0.1

The entry with the earliest start time (09ca3c7f8b68489c8a3c7f8b68b89cdc) summarizes the invocation of the composition while other entries record later activations caused by the composition invocation. There is one entry for each invocation of a composed action (5dceeccbdc7a4caf8eeccbdc7a9caf18 and 7efb6b7354c3472cbb6b7354c3272c98). The remaining entries record the beginning and end of the composition as well as the transitions between the composed actions.

Compositions are implemented by means of OpenWhisk conductor actions. The documentation of conductor actions explains execution traces in greater details.

While composer does not limit in principle the length of a composition, OpenWhisk deployments typically enforce a limit on the number of action invocations in a composition as well as an upper bound on the rate of invocation. These limits may result in compositions failing to execute to completion.

Parallel compositions with Redis

Composer offers parallel combinators that make it possible to run actions or compositions in parallel, for example:

composer.parallel('checkInventory', 'detectFraud')

The width of parallel compositions is not in principle limited by composer, but issuing many concurrent invocations may hit OpenWhisk limits leading to failures: failure to execute a branch of a parallel composition or failure to complete the parallel composition.

These combinators require access to a Redis instance to hold intermediate results of parallel compositions. The Redis credentials may be specified at invocation time or earlier by means of default parameters or package bindings. The required parameter is named $composer. It is a dictionary with a redis field of type dictionary. The redis dictionary specifies the uri for the Redis instance and optionally a certificate as a base64-encoded string to enable TLS connections. Hence, the input parameter object for our order-processing example should be:

{
    "$composer": {
        "redis": {
            "uri": "redis://...",
            "ca": "optional base64 encoded tls certificate"
        }
    },
    "order": { ... }
}

The intent is to store intermediate results in Redis as the parallel composition is progressing. Redis entries are deleted after completion and, as an added safety, expire after twenty-four hours.

OpenWhisk SSL configuration

Additional configuration is required when using an OpenWhisk instance with self-signed certificates to disable SSL certificate validation. The input parameter object must contain a parameter of type dictionary named $composer. This dictionary must contain a dictionary named openwhisk. The openwhisk dictionary must contain a field named ignore_certs with value true:

{
    "$composer": {
        "openwhisk": {
            "ignore_certs": true
        }
    },
    ...
}

This explicit SSL configuration is currently only necessary when using parallel combinators or the async combinator.

Installation from Source

To install composer from a source release, download the composer source code from the Apache OpenWhisk Downloads page, rename the release tarball to openwhisk-composer.tgz and install it with command:

npm install -g openwhisk-composer.tgz

openwhisk-composer's People

Contributors

bdelacretaz avatar dgrove-oss avatar dylandepass avatar jbampton avatar kerryspchang avatar larandersson avatar mrutkows avatar rabbah avatar starpit avatar style95 avatar tardieu avatar travissalascox avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

openwhisk-composer's Issues

Cannot find module 'redis-commands'

Hi, community

The error occurs when I am trying to run a set of parallel actions.

{
"error": "Internal error: Cannot find module 'redis-commands'\nRequire stack:\n- /nodejsAction/runner.js\n- /nodejsAction/src/service.js\n- /nodejsAction/app.js"
}

Here is my basic env info, the /guest/image itself can be run normally

$ wsk action list
actions
/guest/concur-images                                                   private nodejs:14
/guest/image                                                           private python:3

$ node -v
v10.24.0

I also wrote some scripts for building and invoking the parallel actions as below:
concur-images.js

const composer = require('openwhisk-composer');

const workflow = 
    composer.par(
        composer.action("image"),
        composer.action("image"),
        composer.action("image"),
)
module.exports = workflow

build_concur_images.sh

docker stop redis
docker rm redis 

function_name="concur-images"


redis_container_id=$(docker run -itd --name redis -p 6379:6379 redis)

redis_container_ip=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' $redis_container_id)
echo "IP = $redis_container_ip"
echo '{
    "$composer": {
        "openwhisk": {
            "ignore_certs": true
        },
        "redis": {
            "uri": "redis://'${redis_container_ip}':6379"
        }
    }
}' > ${function_name}-input.json


compose $function_name.js > $function_name.json
deploy $function_name $function_name.json -w

invoke-concur-image.sh

wsk action invoke -r /guest/concur-images -P concur-images-input.json

And I just run ./invoke-concur_image.sh after ./build_concur_images.sh, then the error happends.

$ ./build_concur_images.sh 
redis
redis
IP = 172.17.0.2
ok: created action /_/concur-images
$ ./invoke-concur_image.sh 
{
    "error": "Internal error: Cannot find module 'redis-commands'\nRequire stack:\n- /nodejsAction/runner.js\n- /nodejsAction/src/service.js\n- /nodejsAction/app.js"
}

Thank you

repeat loop counter depending on previous result

Hi there,

i would like to know if it is possible to have the compose.repeat configurable?
I have the following scenario.
Function A returns e.g. {number:42}, now i would like to have a compose.repeat which runs 42 times another function B.

IMHO this should be something like this:
compose.seq( functionA, composer.repeat(functionAResult.number, functionB) )
But i didn't figured out how to use a result from a previous function as a counter in the repeat, is this possible?

Thank you!

with webpack bundle optimization, Composer.compile fails

the terser webpack bundle optimizer by default renames javascript classes. as a result, composer.compile fails with

Invalid argument "task" in "task" combinator
Argument value: m {
  '.combinator': [Function: .combinator],
  type: 'action',
  name: '/_/authenticate',
  path: '.test'
}

for now, a workaround is to set keep_classnames: true in the terserOptions passed to the terser webpack plugin constructor.

Add timeout and nodejs version switches support

Currently when deploy composition conductor action code, the default value for timeout is 60s and nodejs version is v6. One would have to manually adjust those options via the UI. It would be nice to have switch support for those options.

Example
deploy ${package}/cos-intellicast-composer intellicast-composer.json -w --kind nodejs:10 --timeout 280000

issue using composer.parallel

Hi Guys - have been trying to use the combinator composer.parallel() but I always get the following error when executing the action,

  • maybe im missing a step? or openwhisk-composer is not compatible with redis inside a docker container?

  • I've setup my redis server in DOCKER and have tested it using the redis explorer in vscode and is working, I can add, delete keys etc.

        "logs": [
            "2020-12-11T06:49:29.0983145Z   stdout: Entering composition[2]",
            "2020-12-11T06:49:29.09834Z     stdout: barrierId: 374ac5cc-44b1-49e5-8605-5398904d62cc, spawning: 2",
            "2020-12-11T06:49:29.0989087Z   stdout: { AbortError: LPUSH can't be processed. The connection is already closed.",
            "2020-12-11T06:49:29.0989191Z   stdout:     at handle_offline_command (/node_modules/redis/index.js:851:15)",
            "2020-12-11T06:49:29.0989227Z   stdout:     at RedisClient.internal_send_command (/node_modules/redis/index.js:885:9)",
            "2020-12-11T06:49:29.0989261Z   stdout:     at RedisClient.lpush (/node_modules/redis/lib/commands.js:58:25)",
            "2020-12-11T06:49:29.0989294Z   stdout:     at Promise (eval at initializeActionHandler (/nodejsAction/runner.js:56:23), <anonymous>:77:12)",
            "2020-12-11T06:49:29.0989328Z   stdout:     at new Promise (<anonymous>)",
            "2020-12-11T06:49:29.098936Z    stdout:     at RedisClient.t.(anonymous function) [as lpushAsync] (eval at initializeActionHandler (/nodejsAction/runner.js:56:23), <anonymous>:76:86)",
            "2020-12-11T06:49:29.098939Z    stdout:     at m (eval at initializeActionHandler (/nodejsAction/runner.js:56:23), <anonymous>:85:39)",
            "2020-12-11T06:49:29.0989422Z   stdout:     at Object.parallel (eval at initializeActionHandler (/nodejsAction/runner.js:56:23), <anonymous>:130:105)",
            "2020-12-11T06:49:29.0989483Z   stdout:     at $ (eval at initializeActionHandler (/nodejsAction/runner.js:56:23), <anonymous>:149:78)",
            "2020-12-11T06:49:29.0989534Z   stdout:     at Promise.resolve.then (eval at initializeActionHandler (/nodejsAction/runner.js:56:23), <anonymous>:154:59)",
            "2020-12-11T06:49:29.0989568Z   stdout:   command: 'LPUSH',",
            "2020-12-11T06:49:29.0989598Z   stdout:   code: 'NR_CLOSED',",
            "2020-12-11T06:49:29.0989631Z   stdout:   args: [ 'composer/fork/374ac5cc-44b1-49e5-8605-5398904d62cc', 42 ] }"
        ]

parameter

 {
        "$composer": {
            "redis": {
                "uri": "redis://127.0.0.1:6379"
            }
        },   
        "value": "from-input" 
}

compose file

const composer = require('openwhisk-composer');

// complexwf.js
module.exports = composer.retain(
    composer.action('step-a', { action: function (params) {
        console.log('log-step-a', params);
        return { value: 'from-step-a' } 
    } }),
    composer.action('step-b', { action: function (params) { 
        console.log('log-step-b', params);
        return { value: 'from-step-b' } 
    } }),
    composer.parallel(
        composer.action('step-c', { action: function (params) { 
            console.log('log-step-c', params);
            return { value: 'from-step-c' } 
        } }),
        composer.action('step-d', { action: function (params) { 
            console.log('log-step-d', params);
            return { value: 'from-step-d' } 
        } }),
    )
);

composer.parallel not available in [email protected]

I've tried using the composer.parallel combinator that was introduced recently, but it returns TypeError: composer.parallel is not a function. I assume they are not packaged into the latest version of openwhisk-composer? May I know the estimated time when the module in npm will be updated to include those combinators?

compose and deploy are two separate commands

compose --deploy in the past allowed one to conveniently lower the composition and deploy it in one command. Now there are two binaries compose and deploy.

what's the rationale for separating them completely (that is, why remove --deploy from compose which could delegate to deploy)?

Document using a source release of Composer

The main README should include some instructions on how to build the composer package from source and use locally without pulling a released convenience binary from npm. This will make the official Apache source release more useful to end-users.

How to set parameters for Redis instance to use parallel composition

Hi,
I'm running OpenWhisk on Kubernetes and my Redis instance is running in a pod. I want to use the parallel combinator but I'll always get the following error Parallel combinator requires a properly configured redis instance when I execute serverless invoke -f conductor.

For me it's not really clear where I have to define the access to my Redis instance. Currently I've defined it in the input parameter object to the parallel composition, but I'm not sure if that's right. Can you please help? Thanks in advance!

Compose file "composition.js":

'use strict';

const composer = require('openwhisk-composer');

module.exports = composer.sequence(
    composer.function(() => ({
        "$composer": {
            "openwhisk": {
                "ignore_certs": true
            },
            "redis": {
                "uri": "redis://redis.default.svc.cluster.local:6379"
            }
        }
    })),
    composer.parallel(
        composer.action('fanOut-dev-alpha'), 
        composer.action('fanOut-dev-alpha')
    )
);

Function file "handler.js":

'use strict';

function alpha(params) {
  return new Promise((resolve) => {setTimeout(resolve, 1000)})
}

module.exports.alpha = alpha;

Serverless file "composition.js":

service: fanOut

provider:
  name: openwhisk
  ignore_certs: true

functions:
  conductor:
    handler: composition.conductor.main
    annotations:
      conductor: true
  alpha:
    handler: handler.alpha

plugins:
  - serverless-openwhisk

http 501 error

I ran the demo example and got the error.

deploy -i -w demo demo.json
OpenWhiskError: PUT https://apihost:port/api/v1/namespaces/_/actions/authenticate Returned HTTP 501 (Not Implemented) --> "Response Missing Error Message."
at Client.handleErrors (/usr/local/lib/node_modules/openwhisk-composer/node_modules/openwhisk/lib/client.js:216:11)
at /usr/local/lib/node_modules/openwhisk-composer/node_modules/openwhisk/lib/client.js:147:58

Did I miss any openwhisk setting in server?

implicit redis dependence causes issues with webpack builds

webpack scans source code for imports, and treats any it thusly discovers as serious statements of dependence. openwhisk-composer has a require('redis'), but no matching dependence resolution in its package.json. as a result, webpack gets a bit confused.

one can place redis (and redis-commands) in the externals section of one's webpack configuration. but... one must do this in a blanket fashion. what if module A of my application has this implicit redis dependence, and module B has an actual (and important) dependence on redis? i cannot therefore take a blanket "externals" treatment of redis, but this is the only option i see, to patch over openwhisk-composer's unstated redis dependence.

Strange behavior with MAP command and actions deployed with concurrency limit greater than one.

System

  • MacBook Pro 13'' 2017
  • Docker Desktop (v.2.5.0.1)
  • Kubernetes (v.1.19.3)
  • opewhisk-composer (v.0.12.0)

Deployment

OpenWhisk platform has been deployed using the following commands (https://github.com/apache/openwhisk-deploy-kube/blob/master/README.md):

kubectl label nodes --all openwhisk-role=invoker
helm install owdev "/.../openwhisk-deploy-kube/helm/openwhisk" \
    -n openwhisk --create-namespace -f "/.../openwhisk-deploy-kube/my_cluster.yaml"

File "my_cluster.yaml" contains:

whisk:
  ingress:
    type: NodePort
    apiHostName: 192.168.65.3
    apiHostPort: 31001
  limits:
    actionsInvokesPerminute: 500
    actionsInvokesConcurrent: 50
    triggersFiresPerminute: 200
    actionsSequenceMaxlength: 70
    actions:
      time:
        min: "100ms"
        max: "5m"
        std: "1m"
      memory:
        min: "128m"
        max: "512m"
        std: "256m"
      concurrency:
        min: 1
        max: 20
        std: 1
      log:
        min: "0m"
        max: "10m"
        std: "10m"
    activation:
      payload:
        max: "1048576"

nginx:
  httpsNodePort: 31001

invoker:
  containerFactory:
    enableConcurrency: true
  options: "-Dwhisk.spi.LogStoreProvider=org.apache.openwhisk.core.containerpool.logging.LogDriverLogStoreProvider -Dwhisk.containerPool.akkaClient=true"

metrics:
  prometheusEnabled: true
  userMetricsEnabled: true

Composition file

const composer = require('openwhisk-composer')

module.exports = composer.sequence(
    composer.action('generator'),
    composer.action('splitter'),
    composer.map('fn1', 'fn2', 'fn3'),
    composer.action('global')
)

Behavior

Once deployed all actions with concurrency limit greater than 1 (I tested with 2, 5, 10, 15, 20), the output of the command wsk -i activation list results in:

Datetime            Activation ID                    Kind      Start Duration   Status  Entity
2020-12-24 01:12:41 4c1fe8f1c8f7408d9fe8f1c8f7a08d04 nodejs:10 warm  45ms       success guest/process_cmp:0.0.2
2020-12-24 01:12:40 be9b99a395a64aac9b99a395a6faac18 nodejs:10 cold  467ms      success guest/global:0.0.1
2020-12-24 01:12:39 8f6a6ef1e7454ce0aa6ef1e7458ce0dc nodejs:10 warm  16ms       success guest/process_cmp:0.0.2
2020-12-24 01:12:39 0cab10a9612144a7ab10a9612144a775 nodejs:10 cold  79ms       success guest/echo:0.0.1
2020-12-24 01:11:49 908844645dbc45838844645dbca5837e nodejs:10 warm  48.321s    success guest/process_cmp:0.0.2
2020-12-24 01:11:49 8c549e0ca77544ec949e0ca775b4ec37 nodejs:10 warm  48.468s    success guest/process_cmp:0.0.2
2020-12-24 01:11:48 5a67e692d72e4ef2a7e692d72e1ef202 nodejs:10 warm  116ms      success guest/fn3:0.0.1
2020-12-24 01:11:48 4988b60f25d2456288b60f25d2356272 nodejs:10 cold  472ms      success guest/fn3:0.0.1
2020-12-24 01:11:46 7b056d4ce3dc4bbb856d4ce3dcfbbbe5 nodejs:10 warm  194ms      success guest/process_cmp:0.0.2
2020-12-24 01:11:46 cb9644cbe9534a359644cbe9534a3580 nodejs:10 warm  123ms      success guest/process_cmp:0.0.2
2020-12-24 01:11:46 f86721155a324b65a721155a32bb652f nodejs:10 warm  21ms       success guest/fn2:0.0.1
2020-12-24 01:11:46 902b4aa654c04f71ab4aa654c02f7155 nodejs:10 cold  105ms      success guest/fn2:0.0.1
2020-12-24 01:11:45 2796dc61d1e54dd896dc61d1e52dd830 nodejs:10 warm  83ms       success guest/process_cmp:0.0.2
2020-12-24 01:11:45 3f16c02dd809465496c02dd809d65459 nodejs:10 warm  32ms       success guest/process_cmp:0.0.2
2020-12-24 01:11:44 f96cd601ccc14757acd601ccc15757c1 nodejs:10 warm  24ms       success guest/fn1:0.0.1
2020-12-24 01:11:44 6b528243ac354264928243ac35126482 nodejs:10 cold  202ms      success guest/fn1:0.0.1
2020-12-24 01:11:44 5287c5e8337144ea87c5e83371f4ea5c nodejs:10 warm  15ms       success guest/process_cmp:0.0.2
2020-12-24 01:11:44 4eca5d53864540738a5d538645907317 nodejs:10 warm  10ms       success guest/process_cmp:0.0.2
2020-12-24 01:11:44 3dac565d34dd41c8ac565d34dd91c823 sequence  warm  54.355s    success guest/process_cmp:0.0.2
2020-12-24 01:11:43 6dd2535b3e05487392535b3e05c873ed sequence  warm  54.402s    success guest/process_cmp:0.0.2
2020-12-24 01:11:43 b5899085af6a44f1899085af6aa4f1aa nodejs:10 warm  55.044s    success guest/process_cmp:0.0.2
2020-12-24 01:11:42 44f71adb9205488cb71adb9205c88cff nodejs:10 cold  107ms      success guest/splitter:0.0.1
2020-12-24 01:11:41 ff1cb1f62e6445039cb1f62e6495037c nodejs:10 warm  24ms       success guest/process_cmp:0.0.2
2020-12-24 01:11:40 00b5adb6bb9e4dc0b5adb6bb9e8dc088 nodejs:10 cold  271ms      success guest/generator:0.0.1
2020-12-24 01:11:39 1fc1f090b83f498181f090b83fa98133 nodejs:10 cold  322ms      success guest/process_cmp:0.0.2
2020-12-24 01:11:38 1c804ece19554b74804ece1955eb74aa sequence  warm  1m3.74s    success guest/process_cmp:0.0.2

Deploying all actions with concurrency limit of 1, the command wsk -i activation list, results in:

Datetime            Activation ID                    Kind      Start Duration   Status  Entity
2020-12-30 03:07:40 e7b4f6f13d574715b4f6f13d571715ce nodejs:10 warm  51ms       success guest/process_cmp:0.0.3
2020-12-30 03:07:39 45458e7de51446c9858e7de51476c9da nodejs:10 cold  143ms      success guest/global:0.0.2
2020-12-30 03:07:38 a20f2d65c7424db88f2d65c742edb86e nodejs:10 warm  54ms       success guest/process_cmp:0.0.3
2020-12-30 03:07:37 664af41682ca43c48af41682cab3c493 nodejs:10 cold  589ms      success guest/fn3:0.0.2
2020-12-30 03:07:37 3bed3685494a49a8ad3685494a59a854 nodejs:10 warm  114ms      success guest/process_cmp:0.0.3
2020-12-30 03:07:35 d03d7bb8eba240d9bd7bb8eba240d930 nodejs:10 cold  1.39s      success guest/fn3:0.0.2
2020-12-30 03:07:33 a3d3d80874a7408893d80874a7b088ab nodejs:10 warm  31ms       success guest/process_cmp:0.0.3
2020-12-30 03:07:32 00206d4a71d04662a06d4a71d0f66278 nodejs:10 cold  596ms      success guest/fn2:0.0.2
2020-12-30 03:07:30 4236ca3f909a4949b6ca3f909a894983 nodejs:10 warm  55ms       success guest/process_cmp:0.0.3
2020-12-30 03:07:29 b69632dee784489d9632dee784f89d42 nodejs:10 cold  176ms      success guest/fn2:0.0.2
2020-12-30 03:07:29 8854a1040d42483e94a1040d42d83e82 nodejs:10 warm  11ms       success guest/process_cmp:0.0.3
2020-12-30 03:07:29 1ae3dc5c0d314d08a3dc5c0d31cd0880 nodejs:10 warm  27ms       success guest/fn1:0.0.2
2020-12-30 03:07:29 a9627bb5899e4346a27bb5899ef346c2 nodejs:10 cold  170ms      success guest/process_cmp:0.0.3
2020-12-30 03:07:28 db61afb2a1fc4c0fa1afb2a1fc8c0fab nodejs:10 warm  176ms      success guest/process_cmp:0.0.3
2020-12-30 03:07:27 e2e788fcaff6424aa788fcaff6624ac8 nodejs:10 cold  265ms      success guest/fn1:0.0.2
2020-12-30 03:07:24 36f41f49d0c14d09b41f49d0c11d0984 nodejs:10 cold  224ms      success guest/process_cmp:0.0.3
2020-12-30 03:07:24 953f42494327425abf42494327625a0a sequence  warm  13.864s    success guest/process_cmp:0.0.3
2020-12-30 03:07:24 60ff7ef4595b41ddbf7ef4595b01ddb0 sequence  warm  14.798s    success guest/process_cmp:0.0.3
2020-12-30 03:07:23 0950037862e740e290037862e760e2f7 nodejs:10 warm  15.118s    success guest/process_cmp:0.0.3
2020-12-30 03:07:23 a8353280c3994a51b53280c399fa5109 nodejs:10 cold  192ms      success guest/splitter:0.0.2
2020-12-30 03:07:22 84c54a91cd9d4c37854a91cd9dec3715 nodejs:10 warm  19ms       success guest/process_cmp:0.0.3
2020-12-30 03:07:21 302fa70cea504175afa70cea5011758e nodejs:10 cold  596ms      success guest/generator:0.0.2
2020-12-30 03:07:19 cc4034d93d9346988034d93d938698ed nodejs:10 cold  589ms      success guest/process_cmp:0.0.3
2020-12-30 03:07:18 154a0556e70b4b0e8a0556e70b7b0eb2 sequence  warm  21.701s    success guest/process_cmp:0.0.3

Problem

Invoking actions deployed with a concurrency limit greater than 1 brings the openwhisk-composer to use echo action to retrieve intermediate result from redis node.

In both cases the composition result is calculated correctly.

The disadvantage is that trying to enable concurrency to have lower latency, the execution time is penalized by:

  • conductor actions which are forced (for some reason) to wait for a timeout to expire;
  • cold starts introduced by a further call to the echo action.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.