usher
Version:
Simple DSL for composing decision workflows for AWS Simple Workflow
167 lines (119 loc) • 5.13 kB
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: decider/tasks/while-loop.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: decider/tasks/while-loop.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>/*!
* Usher
* Copyright(c) 2015 meltmedia <mike@meltmedia.com>
*/
'use strict';
var util = require('util'),
winston = require('winston'),
_ = require('lodash'),
WorkflowExecution = require('../execution'),
Context = require('../context'),
Task = require('./task'),
STATUS = require('./status');
module.exports = WhileLoop;
/**
* The loop executes the `fragment` until the `doneFn` returns a truthy value
*
* @constructor
*/
function WhileLoop(name, deps, fragment, doneFn, options) {
if (!(this instanceof WhileLoop)) {
return new WhileLoop(name, deps, fragment, doneFn, options);
}
Task.apply(this, Array.prototype.slice.call(arguments));
this.fragment = fragment;
if (!_.isFunction(doneFn)) {
throw new Error('You must provide a function to indicate when the loop is complete');
}
this.doneFn = doneFn;
this.options = options || {};
}
util.inherits(WhileLoop, Task);
WhileLoop.prototype.execute = function execute(ctx, done) {
var resolvedName = ctx.namespace ? ctx.namespace + '-' + this.name : this.name,
input = ctx.input(this),
state = ctx.lastState(this),
self = this;
// Make sure we have a state
state = state ? state : { currentIndex: 0 };
// Build the execution context for the current iteration
// Depending on the index, this could be the first of our iterations, or
// picking back up a previously run iteration
var currentExecution = new WorkflowExecution(this.fragment.sequencedTasks()),
currentContext = new Context(ctx.decisionTask, this.name + '-' + state.currentIndex, ctx.localVariables);
// Execute the current context.
// If this is has already been done before, this will drive our state forward.
currentContext.setWorkflowInput(input);
currentExecution.execute(currentContext, function (err) {
if (err) {
winston.log('error', 'An problem occured in while-loop: %s, failing due to: ', resolvedName, err.stack);
return done(STATUS.mask('failed'));
}
handleSuccess();
});
function handleSuccess() {
// If our iteration failed, we mark ourselves as failed
if (currentContext.failed()) {
return done(STATUS.mask('failed'));
}
// Else if current execution has finished running, check to see if it resolves our 'done' state
if (currentContext.done()) {
// We are done, we can mark our task resolved
if (self.doneFn.call(self, currentContext.results)) {
return done(STATUS.mask('complete', 'resolved'));
}
// The last execution did not meet our 'done' criteria so we need to start
// a new execution iteration
state.currentIndex++;
// Save our state
ctx.saveState(self, state);
// Our input can change based on our current state
input = ctx.input(self);
var nextExecution = new WorkflowExecution(self.fragment.sequencedTasks()),
nextContext = new Context(ctx.decisionTask, resolvedName + '-' + state.currentIndex, ctx.localVariables);
// Execute the current context.
// If this is has already been done before, this will drive our state forward.
nextContext.setWorkflowInput(input);
// Since we are scheduling the next iteration we ignore the context status
// When the decider comes back to this loop in it's next decision this context will be evaluated
nextExecution.execute(nextContext, function () {
done(STATUS.mask('outstanding'));
});
} else {
done(STATUS.mask('outstanding'));
}
}
};
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Index</a></h2><h3>Classes</h3><ul><li><a href="Accumulator.html">Accumulator</a></li><li><a href="ActivityPoller.html">ActivityPoller</a></li><li><a href="ActivityTask.html">ActivityTask</a></li><li><a href="DecisionPoller.html">DecisionPoller</a></li><li><a href="Fragment.html">Fragment</a></li><li><a href="Loop.html">Loop</a></li><li><a href="Usher.html">Usher</a></li><li><a href="WhileLoop.html">WhileLoop</a></li><li><a href="WorkflowVersion.html">WorkflowVersion</a></li></ul>
</nav>
<br clear="both">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.3.0-alpha5</a> on Mon Sep 12 2016 14:59:00 GMT-0700 (MST)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>