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
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 && 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 < pending.length; i += 1) {
pendingTask = pending[i];
self.logger.debug("Pending task: \"" + JSON.stringify(pendingTask) + "\"");
if (pendingTask.name === task.name) {
if (task.runtimeInfo && task.runtimeInfo.agentId && (task.runtimeInfo.state === "TASK_RUNNING" || task.runtimeInfo.state === "TASK_STAGING")) {
pendingTask.runtimeInfo = task.runtimeInfo;
pendingTask.taskId = task.taskId;
if (task.commandInfo && task.commandInfo.environment && task.commandInfo.environment.variables && 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>