├── .editorconfig ├── .env.example ├── .gitignore ├── Dockerfile ├── README.md ├── Recursive ├── DisplayTask.js ├── RecursiveWorkflow.js └── RelaunchTask.js ├── Tasks ├── TaskA.js ├── TaskB.js ├── TaskC.js ├── TaskD.js ├── TaskE.js └── TaskWithRetry.js ├── Workflows ├── AsynchronousWorkflow.js ├── AutomaticRetryWorkflow.js ├── ErrorWorkflow.js ├── EventWorkflow.js ├── ParallelWorkflow.js ├── SequentialWorkflow.js ├── VersionWorkflow_v0.js ├── VersionWorkflow_v1.js ├── VersionWorkflow_v2.js ├── WaitEventWorkflow.js └── WaitWorkflow.js ├── boot.js ├── client.js ├── docker-compose.yml ├── launch_asynchronous.js ├── launch_automatic_retry.js ├── launch_error.js ├── launch_event.js ├── launch_parallel.js ├── launch_recursive.js ├── launch_sequential.js ├── launch_task.js ├── launch_version.js ├── launch_wait.js ├── launch_wait_event.js ├── package.json ├── schedule_task_a.js ├── start_zenaton └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 80 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = 0 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # Find your credentials at https://app.zenaton.com/api 2 | ZENATON_APP_ID= 3 | ZENATON_API_TOKEN= 4 | ZENATON_APP_ENV=dev 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Zenaton files 2 | zenaton.* 3 | 4 | # ASDF 5 | .tool-versions 6 | 7 | # Logs 8 | logs 9 | *.log 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Runtime data 15 | pids 16 | *.pid 17 | *.seed 18 | *.pid.lock 19 | 20 | # Directory for instrumented libs generated by jscoverage/JSCover 21 | lib-cov 22 | 23 | # Coverage directory used by tools like istanbul 24 | coverage 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # TypeScript v1 declaration files 46 | typings/ 47 | 48 | # Optional npm cache directory 49 | .npm 50 | 51 | # Optional eslint cache 52 | .eslintcache 53 | 54 | # Optional REPL history 55 | .node_repl_history 56 | 57 | # Output of 'npm pack' 58 | *.tgz 59 | 60 | # Yarn Integrity file 61 | .yarn-integrity 62 | 63 | # dotenv environment variables file 64 | .env 65 | .env.test 66 | 67 | # parcel-bundler cache (https://parceljs.org/) 68 | .cache 69 | 70 | # next.js build output 71 | .next 72 | 73 | # nuxt.js build output 74 | .nuxt 75 | 76 | # vuepress build output 77 | .vuepress/dist 78 | 79 | # Serverless directories 80 | .serverless/ 81 | 82 | # FuseBox cache 83 | .fusebox/ 84 | 85 | # DynamoDB Local files 86 | .dynamodb/ 87 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:stretch 2 | 3 | RUN apt-get update && apt-get install -y curl 4 | 5 | WORKDIR /app 6 | 7 | EXPOSE 4001 8 | 9 | COPY Recursive /app/Recursive 10 | COPY Tasks /app/Tasks 11 | COPY Workflows /app/Workflows 12 | COPY launch* /app/ 13 | COPY boot.js client.js /app/ 14 | 15 | COPY ./start_zenaton /app/start_zenaton 16 | COPY package.json yarn.lock ./ 17 | 18 | # Install application dependencies 19 | RUN yarn 20 | 21 | # Install Zenaton 22 | RUN curl https://install.zenaton.com | sh 23 | 24 | # Launch agent initialization script 25 | CMD ["./start_zenaton"] 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > ⚠️ This repository is abandoned. 2 | 3 |

4 | 5 | 6 |
7 | Easy Asynchronous Jobs Manager for Developers
8 | 9 | Explore the docs » 10 |
11 | Website 12 | · 13 | Node.js Library 14 | · 15 | Tutorial in Node.js
16 |

17 | 18 | # Zenaton examples for Node.js 19 | 20 | [Zenaton](https://zenaton.com) helps developers to easily run, monitor and orchestrate background jobs on your workers without managing a queuing system. 21 | In addition to this, a monitoring dashboard shows you in real-time tasks executions and helps you to handle errors. 22 | 23 | This repository contains examples of workflows built with Zenaton. These examples illustrates how Zenaton orchestrates tasks that are executed on different workers. 24 | 25 | ## Installation 26 | 27 | Download this repo 28 | 29 | ``` 30 | git clone https://github.com/zenaton/examples-node.git && cd examples-node 31 | ``` 32 | 33 | then add an .env file 34 | 35 | ``` 36 | cp -n .env.example .env 37 | ``` 38 | 39 | and populate it with your application id and api token found [here](https://app.zenaton.com/api). 40 | Install dependencies 41 | 42 | ``` 43 | yarn 44 | ``` 45 | 46 | ### Running on Docker 47 | 48 | Simply run 49 | 50 | ``` 51 | docker-compose build; docker-compose up 52 | ``` 53 | 54 | You can check that your agent is running [here](https://app.zenaton.com/agents). 55 | 56 | You're all set! 57 | 58 | ### Running Locally 59 | 60 | Then, you need to install the Zenaton agent 61 | 62 | ``` 63 | curl https://install.zenaton.com | sh 64 | ``` 65 | 66 | and start it, and make it listen to your configuration: 67 | 68 | ``` 69 | zenaton start; zenaton listen --env=.env --boot=boot.js 70 | ``` 71 | 72 | You're all set! 73 | 74 | _Your workflows will be processed by your worker, so you won't see anything except the stdout and stderr, respectively `zenaton.out` and `zenaton.err`. Look at these files :)_ 75 | 76 | ## Example 1: Single task execution 77 | 78 | [This example](https://github.com/zenaton/examples-node/tree/master/Tasks/TaskA.js) showcases 79 | 80 | - A single execution of a task. 81 | 82 | ```sh 83 | node launch_task.js 84 | ``` 85 | 86 | ## Example 2 : Sequential tasks execution 87 | 88 | [This example](https://github.com/zenaton/examples-node/tree/master/Workflows/SequentialWorkflow.js) showcases 89 | 90 | - a sequential execution of three tasks. The second and third tasks are executed only when the previous one is processed. 91 | - In a sequential task execution, you can get the output of a task. The result of a task can be used by the next one. 92 | 93 |

94 |
95 | Sequential Workflow Diagram 100 |

101 | 102 | ```node 103 | node launch_sequential.js 104 | ``` 105 | 106 | ## Example 3: Parallel tasks execution 107 | 108 | [This example](https://github.com/zenaton/examples-node/tree/master/Workflows/ParallelWorkflow.js) showcases 109 | 110 | - a parallel execution of 2 tasks 111 | - a third task that is executed only after _both_ first two tasks were processed 112 | 113 |

114 | Parallel Workflow Diagram 119 | 120 | 121 |

122 | 123 | ```node 124 | node launch_parallel.js 125 | ``` 126 | 127 | ## Example 4: Asynchronous tasks execution 128 | 129 | [this example](https://github.com/zenaton/examples-node/tree/master/Workflows/AsynchronousWorkflow.js) showcases 130 | 131 | - Asynchronous executions of Task A and Task B (fire and forget) 132 | - Then sequential executions of Task C and Task D 133 | 134 |

135 | Asynchronous Workflow Diagram 140 | 141 | 142 |

143 | 144 | ```node 145 | node launch_asynchronous.js 146 | ``` 147 | 148 | When a task is dispatched asynchronously, the workflow continues its execution without waiting for the task completion. Consequently, a task asynchronous dispatching always returns a null value. 149 | 150 | ## Example 5: Event 151 | 152 | [This example](https://github.com/zenaton/examples-node/tree/master/Workflows/EventWorkflow.js) showcases 153 | 154 | - how to change a workflow's behaviour based on an external event 155 | 156 |

157 | Event Workflow Diagram 162 | 163 |

164 | 165 | ```node 166 | node launch_event.js 167 | ``` 168 | 169 | ## Example 6: Wait 170 | 171 | [This example](https://github.com/zenaton/examples-node/tree/master/Workflows/WaitWorkflow.js) showcases 172 | 173 | - how the provided `Wait` task can be used to pause the workflow for a specified duration 174 | 175 |

176 | Wait Workflow Diagram 181 | 182 |

183 | 184 | ```node 185 | node launch_wait.js 186 | ``` 187 | 188 | ## Example 7: Wait Event 189 | 190 | [This example](https://github.com/zenaton/examples-node/tree/master/Workflows/WaitEventWorkflow.js) showcases 191 | 192 | - how the provided `Wait` task can also be used to pause the workflow up to receiving a specific external event 193 | 194 |

195 | WaitEvent Workflow Diagram 200 | 201 |

202 | 203 | ```node 204 | node launch_wait_event.js 205 | ``` 206 | 207 | ## Example 8: Recursive Workflow 208 | 209 | [This example](https://github.com/zenaton/examples-node/tree/master/Recursive) showcases 210 | 211 | - how launching events or workflows directly from orchestrated tasks allows you to schedule recurring workflows 212 | 213 | ```node 214 | node launch_recursive.js 215 | ``` 216 | 217 | ## Example 9: Workflow Versions 218 | 219 | [This example](https://github.com/zenaton/examples-node/tree/master/Workflows/VersionWorkflow.js) showcases 220 | 221 | - how to update your workflow implementation, even while previous versions are still running 222 | 223 | ```node 224 | node launch_version.js 225 | ``` 226 | 227 | ## Example 10: Managing Errors 228 | 229 | [This example](https://github.com/zenaton/examples-node/tree/master/Workflows/ErrorWorkflow.js) showcases 230 | 231 | - how a failed task appear on Zenaton website 232 | - how to retry a failed task using the retry button 233 | 234 |

235 | Error Workflow Diagram 240 | 241 |

242 | 243 | ```node 244 | node launch_error.js 245 | ``` 246 | 247 | ## Example 11: Automatic retry of failed tasks 248 | 249 | [This example](https://github.com/zenaton/examples-node/tree/master/Tasks/TaskWithRetry.js) showcases 250 | 251 | - how a failed task can be retried automatically 252 | - how to customize the automatic retry policy 253 | 254 | ```node 255 | node launch_automatic_retry.js 256 | ``` 257 | 258 | ## Example 12: Schedule a task 259 | 260 | [This example](https://github.com/zenaton/examples-node/tree/master/schedule_task_a.js) showcases 261 | 262 | - how to schedule a task to make it run periodically 263 | 264 | ```node 265 | node schedule_task_a.js 266 | ``` 267 | -------------------------------------------------------------------------------- /Recursive/DisplayTask.js: -------------------------------------------------------------------------------- 1 | module.exports.handle = async counter => { 2 | console.log(counter); 3 | 4 | await new Promise(resolve => { 5 | setTimeout(resolve, 100); 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /Recursive/RecursiveWorkflow.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports.handle = function*(id, max) { 4 | let counter = 0; 5 | 6 | while (counter < 10) { 7 | yield this.run.task("DisplayTask", counter); 8 | counter++; 9 | } 10 | 11 | if (id < max) { 12 | yield this.run.task("RelaunchTask", 1 + id, max); 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /Recursive/RelaunchTask.js: -------------------------------------------------------------------------------- 1 | const { run } = require("../client"); 2 | 3 | module.exports.handle = async (id, max) => { 4 | console.log(`\nIteration: ${id}`); 5 | 6 | run.withTag(id).workflow("RecursiveWorkflow", id, max); 7 | }; 8 | -------------------------------------------------------------------------------- /Tasks/TaskA.js: -------------------------------------------------------------------------------- 1 | module.exports.handle = async function() { 2 | console.log("Task A starts"); 3 | 4 | await new Promise(resolve => { 5 | setTimeout(resolve, 3000); 6 | }); 7 | 8 | console.log("Task A ends"); 9 | 10 | return 0; 11 | }; 12 | -------------------------------------------------------------------------------- /Tasks/TaskB.js: -------------------------------------------------------------------------------- 1 | module.exports.handle = async function() { 2 | console.log("Task B starts"); 3 | 4 | await new Promise(resolve => { 5 | setTimeout(resolve, 5000); 6 | }); 7 | 8 | console.log("Task B ends"); 9 | 10 | return 1; 11 | }; 12 | -------------------------------------------------------------------------------- /Tasks/TaskC.js: -------------------------------------------------------------------------------- 1 | module.exports.handle = async function() { 2 | console.log("Task C starts"); 3 | 4 | await new Promise(resolve => { 5 | setTimeout(resolve, 7000); 6 | }); 7 | 8 | console.log("Task C ends"); 9 | 10 | return 2; 11 | }; 12 | -------------------------------------------------------------------------------- /Tasks/TaskD.js: -------------------------------------------------------------------------------- 1 | module.exports.handle = async function() { 2 | console.log("Task D starts"); 3 | 4 | await new Promise(resolve => { 5 | setTimeout(resolve, 9000); 6 | }); 7 | 8 | console.log("Task D ends"); 9 | 10 | return 3; 11 | }; 12 | -------------------------------------------------------------------------------- /Tasks/TaskE.js: -------------------------------------------------------------------------------- 1 | module.exports.handle = async function() { 2 | console.log("Task E starts"); 3 | 4 | throw new Error("Error in TaskE"); 5 | 6 | console.log("Task E ends"); 7 | }; 8 | -------------------------------------------------------------------------------- /Tasks/TaskWithRetry.js: -------------------------------------------------------------------------------- 1 | module.exports.handle = async function() { 2 | console.log("TaskWithRetry starts"); 3 | 4 | await new Promise(resolve => { 5 | setTimeout(resolve, 3000); 6 | }); 7 | 8 | throw new Error("Error in TaskWithRetry"); 9 | 10 | console.log("TaskWithRetry ends"); 11 | 12 | return 0; 13 | }; 14 | 15 | module.exports.onErrorRetryDelay = function(error) { 16 | // The retry index starts at 1 and increases by one for every retry. 17 | // This can be used to to increase the time between each attempt. 18 | const n = this.context.retryIndex; 19 | if (n > 3) { 20 | return false; 21 | } 22 | 23 | return n * 5; 24 | }; 25 | -------------------------------------------------------------------------------- /Workflows/AsynchronousWorkflow.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports.handle = function*() { 4 | this.run.task("TaskA"); 5 | this.run.task("TaskB"); 6 | yield this.run.task("TaskC"); 7 | yield this.run.task("TaskD"); 8 | }; 9 | -------------------------------------------------------------------------------- /Workflows/AutomaticRetryWorkflow.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports.handle = function*() { 4 | yield this.run.task("TaskWithRetry"); 5 | }; 6 | -------------------------------------------------------------------------------- /Workflows/ErrorWorkflow.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports.handle = function*() { 4 | yield this.run.task(["TaskA"], ["TaskE"]); 5 | yield this.run.task("TaskC"); 6 | }; 7 | -------------------------------------------------------------------------------- /Workflows/EventWorkflow.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = { 4 | *handle() { 5 | this.state = true; 6 | yield this.run.task("TaskA"); 7 | // if "MyEvent" has been received during "TaskA" processing 8 | // do "TaskB", otherwise do "TaskC" 9 | if (this.state) { 10 | yield this.run.task("TaskB"); 11 | } else { 12 | yield this.run.task("TaskC"); 13 | } 14 | }, 15 | *onEvent(name, data) { 16 | if (name === "MyEvent") { 17 | this.state = false; 18 | } 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /Workflows/ParallelWorkflow.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports.handle = function*() { 4 | // We start 2 tasks in parallel 5 | const [a, b] = yield this.run.task(["TaskA"], ["TaskB"]); 6 | 7 | // Then do something with both results 8 | if (a > b) { 9 | this.run.task("TaskC"); 10 | } else { 11 | this.run.task("TaskD"); 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /Workflows/SequentialWorkflow.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports.handle = function*() { 4 | const a = yield this.run.task("TaskA"); 5 | 6 | if (0 < a) { 7 | yield this.run.task("TaskB"); 8 | } else { 9 | yield this.run.task("TaskC"); 10 | } 11 | 12 | yield this.run.task("TaskD"); 13 | }; 14 | -------------------------------------------------------------------------------- /Workflows/VersionWorkflow_v0.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports.handle = function*() { 4 | this.run.task("TaskA"); 5 | yield this.run.task("TaskB"); 6 | yield this.wait.event("MyEvent").forever(); 7 | }; 8 | 9 | module.exports.onEvent = function*(name) { 10 | console.log(`Event ${name} received for Version 0`); 11 | }; 12 | -------------------------------------------------------------------------------- /Workflows/VersionWorkflow_v1.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports.handle = function*() { 4 | this.run.task("TaskA"); 5 | this.run.task("TaskB"); 6 | yield this.run.task("TaskC"); 7 | yield this.wait.event("MyEvent").forever(); 8 | }; 9 | 10 | module.exports.onEvent = function*(name) { 11 | console.log(`Event ${name} received for Version 1`); 12 | }; 13 | -------------------------------------------------------------------------------- /Workflows/VersionWorkflow_v2.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports.handle = function*() { 4 | this.run.task("TaskA"); 5 | this.run.task("TaskB"); 6 | this.run.task("TaskC"); 7 | yield this.run.task("TaskD"); 8 | yield this.wait.event("MyEvent").forever(); 9 | }; 10 | 11 | module.exports.onEvent = function*() { 12 | console.log("Event received for Version 2"); 13 | }; 14 | -------------------------------------------------------------------------------- /Workflows/WaitEventWorkflow.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { duration } = require("zenaton"); 4 | 5 | module.exports.handle = function*() { 6 | // Waiting for an "MyEvent" event, at most 30 seconds 7 | const event = yield this.wait.event("MyEvent").for(duration.seconds(30)); 8 | // Do "TaskA" if "MyEvent" has been received within 30s, otherwise "TaskB" 9 | if (event) { 10 | yield this.run.task("TaskA"); 11 | } else { 12 | yield this.run.task("TaskB"); 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /Workflows/WaitWorkflow.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { duration } = require("zenaton"); 4 | 5 | module.exports.handle = function*() { 6 | yield this.run.task("TaskA"); 7 | yield this.wait.for(duration.seconds(15)); 8 | yield this.run.task("TaskB"); 9 | }; 10 | -------------------------------------------------------------------------------- /boot.js: -------------------------------------------------------------------------------- 1 | const { task, workflow } = require("zenaton"); 2 | 3 | // workflow definitions 4 | workflow("SequentialWorkflow", require("./Workflows/SequentialWorkflow")); 5 | workflow("AsynchronousWorkflow", require("./Workflows/AsynchronousWorkflow")); 6 | workflow("WaitWorkflow", require("./Workflows/WaitWorkflow")); 7 | workflow("EventWorkflow", require("./Workflows/EventWorkflow")); 8 | workflow("WaitEventWorkflow", require("./Workflows/WaitEventWorkflow")); 9 | workflow("ErrorWorkflow", require("./Workflows/ErrorWorkflow")); 10 | workflow("VersionWorkflow_v0", require("./Workflows/VersionWorkflow_v0")); 11 | workflow("VersionWorkflow_v1", require("./Workflows/VersionWorkflow_v1")); 12 | workflow("VersionWorkflow_v2", require("./Workflows/VersionWorkflow_v2")); 13 | workflow("ParallelWorkflow", require("./Workflows/ParallelWorkflow")); 14 | workflow("AutomaticRetryWorkflow", require("./Workflows/AutomaticRetryWorkflow")); 15 | 16 | // tasks definitions 17 | task("TaskA", require("./Tasks/TaskA")); 18 | task("TaskB", require("./Tasks/TaskB")); 19 | task("TaskC", require("./Tasks/TaskC")); 20 | task("TaskD", require("./Tasks/TaskD")); 21 | task("TaskE", require("./Tasks/TaskE")); 22 | task("TaskWithRetry", require("./Tasks/TaskWithRetry")); 23 | 24 | // recursive workflow and its tasks definitions 25 | workflow("RecursiveWorkflow", require("./Recursive/RecursiveWorkflow")); 26 | task("DisplayTask", require("./Recursive/DisplayTask")); 27 | task("RelaunchTask", require("./Recursive/RelaunchTask")); 28 | -------------------------------------------------------------------------------- /client.js: -------------------------------------------------------------------------------- 1 | // load .env file 2 | const fs = require("fs"); 3 | const dotenv = require("dotenv"); 4 | const dotenvfile = __dirname + "/.env"; 5 | 6 | if (fs.existsSync(dotenvfile)) { 7 | dotenv.config({ path: dotenvfile }); 8 | } 9 | 10 | const { Client } = require("zenaton"); 11 | 12 | const app_id = process.env.ZENATON_APP_ID; 13 | if (!app_id) { 14 | console.log( 15 | "Please add your Zenaton application id on '.env' file (https://app.zenaton.com/api)" 16 | ); 17 | process.exit(1); 18 | } 19 | 20 | const api_token = process.env.ZENATON_API_TOKEN; 21 | if (!api_token) { 22 | console.log( 23 | "Please add your Zenaton api token on '.env' file (https://app.zenaton.com/api)" 24 | ); 25 | process.exit(1); 26 | } 27 | 28 | const app_env = process.env.ZENATON_APP_ENV; 29 | if (!app_env) { 30 | console.log( 31 | "Please add your Zenaton environment on '.env' file (https://app.zenaton.com/api)" 32 | ); 33 | process.exit(1); 34 | } 35 | 36 | // init Zenaton client 37 | module.exports = new Client(app_id, api_token, app_env); 38 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | app: 4 | build: . 5 | volumes: 6 | - node_modules:/app/node_modules 7 | - .:/app 8 | ports: 9 | - "4001:4001" 10 | env_file: 11 | - .env 12 | volumes: 13 | node_modules: 14 | -------------------------------------------------------------------------------- /launch_asynchronous.js: -------------------------------------------------------------------------------- 1 | const { run } = require("./client"); 2 | 3 | run.workflow("AsynchronousWorkflow"); 4 | -------------------------------------------------------------------------------- /launch_automatic_retry.js: -------------------------------------------------------------------------------- 1 | const { run } = require("./client"); 2 | 3 | run.workflow("AutomaticRetryWorkflow"); 4 | 5 | -------------------------------------------------------------------------------- /launch_error.js: -------------------------------------------------------------------------------- 1 | const { run } = require("./client"); 2 | 3 | run.workflow("ErrorWorkflow"); 4 | -------------------------------------------------------------------------------- /launch_event.js: -------------------------------------------------------------------------------- 1 | const uniqid = require("uniqid"); 2 | const { run, select } = require("./client"); 3 | 4 | const tag = `id:${uniqid()}`; 5 | 6 | run.withTag(tag).workflow("EventWorkflow"); 7 | 8 | setTimeout(function() { 9 | select 10 | .workflow("EventWorkflow") 11 | .withTag(tag) 12 | .send("MyEvent"); 13 | }, 1000); 14 | -------------------------------------------------------------------------------- /launch_parallel.js: -------------------------------------------------------------------------------- 1 | const { run } = require("./client"); 2 | 3 | run.workflow("ParallelWorkflow"); 4 | -------------------------------------------------------------------------------- /launch_recursive.js: -------------------------------------------------------------------------------- 1 | const { run } = require("./client"); 2 | 3 | run.task("RelaunchTask", 1, 10); 4 | -------------------------------------------------------------------------------- /launch_sequential.js: -------------------------------------------------------------------------------- 1 | const run = require("./client").run; 2 | 3 | run.workflow("SequentialWorkflow"); 4 | -------------------------------------------------------------------------------- /launch_task.js: -------------------------------------------------------------------------------- 1 | const { run } = require("./client"); 2 | 3 | run.task("TaskA"); 4 | -------------------------------------------------------------------------------- /launch_version.js: -------------------------------------------------------------------------------- 1 | const uniqid = require("uniqid"); 2 | const { run, select } = require("./client"); 3 | 4 | const tag = `id:${uniqid()}`; 5 | // dispatch a workflow 6 | run.withTag(tag).workflow("VersionWorkflow"); 7 | 8 | // then send it an event 9 | setTimeout(function() { 10 | select 11 | .workflow("VersionWorkflow") 12 | .withTag(tag) 13 | .send("MyEvent"); 14 | }, 5000); 15 | -------------------------------------------------------------------------------- /launch_wait.js: -------------------------------------------------------------------------------- 1 | const run = require("./client").run; 2 | 3 | run.workflow("WaitWorkflow"); 4 | -------------------------------------------------------------------------------- /launch_wait_event.js: -------------------------------------------------------------------------------- 1 | const uniqid = require("uniqid"); 2 | const { run, select } = require("./client"); 3 | 4 | // my id 5 | const tag = `id:${uniqid()}`; 6 | 7 | // dispatch a workflow 8 | run.withTag(tag).workflow("WaitEventWorkflow"); 9 | 10 | // then send it an event 11 | setTimeout(function() { 12 | select 13 | .workflow("WaitEventWorkflow") 14 | .withTag(tag) 15 | .send("MyEvent"); 16 | }, 5000); 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "examples-javascript", 3 | "version": "1.1.0", 4 | "main": "index.js", 5 | "repository": "https://github.com/zenaton/examples-node.git", 6 | "author": "Zenaton Inc", 7 | "license": "MIT", 8 | "bugs": { 9 | "url": "https://github.com/zenaton/examples-node/issues" 10 | }, 11 | "homepage": "https://zenaton.com", 12 | "engines": { 13 | "node": ">=8.0.0" 14 | }, 15 | "dependencies": { 16 | "dotenv": "6.2.0", 17 | "uniqid": "5.0.3", 18 | "zenaton": "^0.8.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /schedule_task_a.js: -------------------------------------------------------------------------------- 1 | const { schedule } = require("./client"); 2 | 3 | schedule("* * * * * *").task("TaskA") 4 | -------------------------------------------------------------------------------- /start_zenaton: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | # Make sure dependencies are installed 6 | yarn 7 | 8 | # Start zenaton agent 9 | zenaton start 10 | zenaton listen --env=.env --boot=boot.js 11 | 12 | # Log agent output 13 | touch zenaton.out 14 | tail -f zenaton.out 15 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/runtime@7.5.5": 6 | version "7.5.5" 7 | resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" 8 | integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== 9 | dependencies: 10 | regenerator-runtime "^0.13.2" 11 | 12 | axios@0.19.0: 13 | version "0.19.0" 14 | resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8" 15 | integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ== 16 | dependencies: 17 | follow-redirects "1.5.10" 18 | is-buffer "^2.0.2" 19 | 20 | cross-fetch@2.2.2: 21 | version "2.2.2" 22 | resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.2.tgz#a47ff4f7fc712daba8f6a695a11c948440d45723" 23 | integrity sha1-pH/09/xxLauo9qaVoRyUhEDUVyM= 24 | dependencies: 25 | node-fetch "2.1.2" 26 | whatwg-fetch "2.0.4" 27 | 28 | debug@=3.1.0: 29 | version "3.1.0" 30 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" 31 | integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== 32 | dependencies: 33 | ms "2.0.0" 34 | 35 | dotenv@6.2.0: 36 | version "6.2.0" 37 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.2.0.tgz#941c0410535d942c8becf28d3f357dbd9d476064" 38 | integrity sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w== 39 | 40 | follow-redirects@1.5.10: 41 | version "1.5.10" 42 | resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" 43 | integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== 44 | dependencies: 45 | debug "=3.1.0" 46 | 47 | graphql-request@^1.8.2: 48 | version "1.8.2" 49 | resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-1.8.2.tgz#398d10ae15c585676741bde3fc01d5ca948f8fbe" 50 | integrity sha512-dDX2M+VMsxXFCmUX0Vo0TopIZIX4ggzOtiCsThgtrKR4niiaagsGTDIHj3fsOMFETpa064vzovI+4YV4QnMbcg== 51 | dependencies: 52 | cross-fetch "2.2.2" 53 | 54 | is-buffer@^2.0.2: 55 | version "2.0.4" 56 | resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" 57 | integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== 58 | 59 | moment-timezone@0.5.26: 60 | version "0.5.26" 61 | resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.26.tgz#c0267ca09ae84631aa3dc33f65bedbe6e8e0d772" 62 | integrity sha512-sFP4cgEKTCymBBKgoxZjYzlSovC20Y6J7y3nanDc5RoBIXKlZhoYwBoZGe3flwU6A372AcRwScH8KiwV6zjy1g== 63 | dependencies: 64 | moment ">= 2.9.0" 65 | 66 | "moment@>= 2.9.0": 67 | version "2.24.0" 68 | resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" 69 | integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== 70 | 71 | ms@2.0.0: 72 | version "2.0.0" 73 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 74 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 75 | 76 | node-fetch@2.1.2: 77 | version "2.1.2" 78 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" 79 | integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= 80 | 81 | regenerator-runtime@^0.13.2: 82 | version "0.13.3" 83 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5" 84 | integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw== 85 | 86 | uniqid@5.0.3: 87 | version "5.0.3" 88 | resolved "https://registry.yarnpkg.com/uniqid/-/uniqid-5.0.3.tgz#917968310edc868d50df6c44f783f32c7d80fac1" 89 | integrity sha512-R2qx3X/LYWSdGRaluio4dYrPXAJACTqyUjuyXHoJLBUOIfmMcnYOyY2d6Y4clZcIz5lK6ZaI0Zzmm0cPfsIqzQ== 90 | 91 | uuid@^3.3.3: 92 | version "3.4.0" 93 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" 94 | integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== 95 | 96 | whatwg-fetch@2.0.4: 97 | version "2.0.4" 98 | resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" 99 | integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== 100 | 101 | zenaton@^0.8.0: 102 | version "0.8.0" 103 | resolved "https://registry.yarnpkg.com/zenaton/-/zenaton-0.8.0.tgz#67d54fd85b24a94674604029bc84f9eeca8e0ae4" 104 | integrity sha512-fqo3Z2lXUuscLlR03T50r6yDVPif1n0mEj0A9mtHLlJLM8bWa0AOHrxxkKVqXbDFfVsaET0XWFR8R5xIVC+yRQ== 105 | dependencies: 106 | "@babel/runtime" "7.5.5" 107 | axios "0.19.0" 108 | graphql-request "^1.8.2" 109 | moment-timezone "0.5.26" 110 | uuid "^3.3.3" 111 | --------------------------------------------------------------------------------