UNPKG

mesos-framework

Version:

A wrapper around the Mesos HTTP APIs for Schedulers and Executors. Write your Mesos framework in pure JavaScript!

212 lines (185 loc) 14.4 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>taskHelper.js - Documentation</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="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css"> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <input type="checkbox" id="nav-trigger" class="nav-trigger" /> <label for="nav-trigger" class="navicon-button x"> <div class="navicon"></div> </label> <label for="nav-trigger" class="overlay"></label> <nav> <li class="nav-link nav-home-link"><a href="index.html">Home</a></li><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Builder.html">Builder</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Executor.html">Executor</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Executor.html#message">message</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Executor.html#subscribe">subscribe</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Executor.html#update">update</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Mesos.html">Mesos</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Mesos.html#build">build</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Mesos.html#getBuilder">getBuilder</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Mesos.html#getMesos">getMesos</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Mesos.html#getProtoBuf">getProtoBuf</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Scheduler.html">Scheduler</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Scheduler.html#accept">accept</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Scheduler.html#acceptInverseOffers">acceptInverseOffers</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Scheduler.html#acknowledge">acknowledge</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Scheduler.html#acknowledgeOperationStatus">acknowledgeOperationStatus</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Scheduler.html#backOff">backOff</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Scheduler.html#decline">decline</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Scheduler.html#declineInverseOffers">declineInverseOffers</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Scheduler.html#getRunningTasks">getRunningTasks</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Scheduler.html#kill">kill</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Scheduler.html#message">message</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Scheduler.html#reconcile">reconcile</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Scheduler.html#reconcileOperations">reconcileOperations</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Scheduler.html#request">request</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Scheduler.html#revive">revive</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Scheduler.html#shutdown">shutdown</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Scheduler.html#subscribe">subscribe</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Scheduler.html#suppress">suppress</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Scheduler.html#sync">sync</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Scheduler.html#teardown">teardown</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="TaskHealthHelper.html">TaskHealthHelper</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="TaskHelper.html">TaskHelper</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="TaskHelper.html#deleteTask">deleteTask</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="TaskHelper.html#loadTasks">loadTasks</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="TaskHelper.html#saveTask">saveTask</a></span></li> </nav> <div id="main"> <h1 class="page-title">taskHelper.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>"use strict"; var lib = require("requirefrom")("lib"); var Mesos = require("./mesos")().getMesos(); var Builder = lib("builder"); /** * Represents a TaskHelper object * @constructor * @param {object} scheduler - The scheduler object. */ function TaskHelper(scheduler) { if (!(this instanceof TaskHelper)) { return new TaskHelper(scheduler); } var self = this; self.zkClient = scheduler.zkClient; self.scheduler = scheduler; self.logger = scheduler.logger; self.zkServicePath = self.scheduler.zkServicePath; } /** * Load the task nodes belonging to the framework from ZooKeeper. */ TaskHelper.prototype.loadTasks = function() { var self = this; self.zkClient.getChildren(self.zkServicePath + "/tasks", function (error, children, stat) { if (error) { self.logger.error("Could not load task information."); // We're ready to subscribe self.scheduler.emit("ready"); } else if (children &amp;&amp; children.length) { var childStates = {}; children.forEach(function (child) { self.zkClient.getData(self.zkServicePath + "/tasks/" + child, function (error, data, stat) { if (error || !data) { self.logger.error("Could not load task information for " + child); if (!error) { self.deleteTask(child); } childStates[child] = {'loaded': false}; self.logger.debug("childStates length " + Object.keys(childStates).length.toString() + " children.length " + children.length.toString()); if (Object.keys(childStates).length === children.length) { // We're ready to subscribe self.scheduler.emit("ready"); } return; } var pending = self.scheduler.pendingTasks; self.scheduler.pendingTasks = []; var task = JSON.parse(data.toString()); self.logger.debug("Loading task: " + JSON.stringify(task)); var found = false; var i = 0; var pendingTask; function addVars(variable) { // Check if variable name is either HOST or PORT# -> Set by this framework when starting a task - copy it to the loaded task if (variable.name.match(/^HOST$/) !== null || variable.name.match(/^PORT[0-9]+/) !== null) { // Add all matching (non-user-defined) environment variables pendingTask.commandInfo.environment.variables.push(variable); } } for (i = 0; i &lt; pending.length; i += 1) { pendingTask = pending[i]; self.logger.debug("Pending task: \"" + JSON.stringify(pendingTask) + "\""); if (pendingTask.name === task.name) { if (task.runtimeInfo &amp;&amp; task.runtimeInfo.agentId &amp;&amp; (task.runtimeInfo.state === "TASK_RUNNING" || task.runtimeInfo.state === "TASK_STAGING")) { pendingTask.runtimeInfo = task.runtimeInfo; pendingTask.taskId = task.taskId; if (task.commandInfo &amp;&amp; task.commandInfo.environment &amp;&amp; task.commandInfo.environment.variables &amp;&amp; task.commandInfo.environment.variables.length > 0) { if (!pendingTask.commandInfo) { pendingTask.commandInfo = new Builder("mesos.CommandInfo") .setEnvironment(new Mesos.Environment([])) .setShell(false); } if (!pendingTask.commandInfo.environment) { pendingTask.commandInfo.environment = new Mesos.Environment([]); } // Iterate over all environment variables task.commandInfo.environment.variables.forEach(addVars); } self.scheduler.launchedTasks.push(pendingTask); pending.splice(i, 1); self.scheduler.reconcileTasks.push(pendingTask); } else { self.deleteTask(task.taskId); } found = true; break; } } if (!found) { self.logger.info("Setting task ID " + task.taskId + " to be killed"); self.scheduler.killTasks.push(task); } self.scheduler.pendingTasks = pending; childStates[child] = {'loaded': true}; self.logger.debug("childStates length " + Object.keys(childStates).length.toString() + " children.length " + children.length.toString()); if (Object.keys(childStates).length === children.length) { // We're ready to subscribe self.scheduler.emit("ready"); } }); }); } else { // We're ready to subscribe - no tasks self.scheduler.emit("ready"); } }); }; /** * Save task nodes from ZooKeeper. * @param {object} task - The task object which should be persisted to ZooKeeper. */ TaskHelper.prototype.saveTask = function (task) { var self = this; var data = new Buffer(JSON.stringify(task)); // Seperating path creation from data save due to various client bugs. self.zkClient.mkdirp(self.zkServicePath+"/tasks/" + task.taskId, function (error, stat){ if (error) { self.logger.error("Got error when creating task node in ZK " + task.name + " ID " + task.taskId + " data: " + error); return; } self.zkClient.setData(self.zkServicePath+"/tasks/" + task.taskId, data, function (error, stat) { if (error) { self.logger.error("Got error when saving task " + task.name + " ID " + task.taskId + " data: " + error); return; } self.logger.debug("Saved task " + task.name + " ID " + task.taskId); }); }); }; /** * Delete task nodes from ZooKeeper. * @param {string} taskId - The id of the task which should be deleted from ZooKeeper. */ TaskHelper.prototype.deleteTask = function (taskId) { var self = this; self.zkClient.remove(self.zkServicePath + "/tasks/" + taskId, function (error) { if (error) { self.logger.error("Error deleting task ID " + taskId + " from zookeeper"); } else { self.logger.debug("Deleted task " + taskId + " from zookeeper"); } }); }; module.exports = TaskHelper; </code></pre> </article> </section> </div> <br class="clear"> <footer> Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Mar 04 2018 17:37:29 GMT+0100 (CET) using the Minami theme. </footer> <script>prettyPrint();</script> <script src="scripts/linenumber.js"></script> </body> </html>