mesos-framework
Version:
A wrapper around the Mesos HTTP APIs for Schedulers and Executors. Write your Mesos framework in pure JavaScript!
226 lines (175 loc) • 13.3 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>taskHealthHelper.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">taskHealthHelper.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>"use strict";
var http = require("http");
/**
* Represents a TaskHealthHelper object
* @constructor
* @param {object} scheduler - The scheduler object.
* @param {object} options - The option map object.
*/
function TaskHealthHelper(scheduler, options) {
if (!(this instanceof TaskHealthHelper)) {
return new TaskHealthHelper(scheduler, options);
}
var self = this;
self.scheduler = scheduler;
self.logger = scheduler.logger;
self.options = {};
self.options.interval = options.interval || 30;
self.options.graceCount = options.graceCount || 4;
self.options.portIndex = options.portIndex || 0;
self.options.propertyPrefix = options.propertyPrefix || "";
self.options.errorEvent = options.errorEvent || self.options.propertyPrefix + "task_unhealthy";
self.options.additionalProperties = options.additionalProperties || [];
self.options.taskNameFilter = options.taskNameFilter || null;
self.options.statusCodes = options.statusCodes || [200];
self.options.checkBodyFunction = options.checkBodyFunction || null;
if (options.url) {
self.options.url = options.url;
} else {
throw new Error("Must set URL");
}
self.healthRequestCreate = function (host, port) {
return {
"host": host,
"port": port,
"path": options.url,
"method": "GET",
headers: {}
};
};
self.checkRunningInstances = function () {
self.logger.debug("Running periodic healthcheck" + (self.options.propertyPrefix.length ? ", prefix: " + self.options.propertyPrefix : ""));
self.scheduler.launchedTasks.forEach(function (task) {
self.checkInstance.call(self, task);
});
};
}
TaskHealthHelper.prototype.taskFilter = function (name) {
var self = this;
if (self.options.taskNameFilter) {
return name.match(self.options.taskNameFilter) !== null;
}
return true;
};
TaskHealthHelper.prototype.setCheckFailed = function (task) {
var self = this;
if (task.runtimeInfo[self.options.propertyPrefix + "checkFailCount"] === undefined) {
task.runtimeInfo[self.options.propertyPrefix + "checkFailCount"] = 0;
}
task.runtimeInfo[self.options.propertyPrefix + "checkFailCount"] += 1;
if (task.runtimeInfo[self.options.propertyPrefix + "checkFailCount"] === self.options.graceCount) {
self.logger.debug("Task marked unhealthy" + (self.options.propertyPrefix.length ? ", prefix: " + self.options.propertyPrefix : ""));
task.runtimeInfo[self.options.propertyPrefix + "healthy"] = false;
self.setProperties(task, false);
self.scheduler.emit(self.options.errorEvent, task);
} else if (task.runtimeInfo[self.options.propertyPrefix + "healthy"] === false) {
self.scheduler.emit(self.options.errorEvent, task);
}
};
TaskHealthHelper.prototype.checkInstance = function (task) {
var self = this;
if (task.runtimeInfo && task.runtimeInfo.state === "TASK_RUNNING" && self.taskFilter(task.name)) {
if (task.runtimeInfo.network && task.runtimeInfo.network.hostname && task.runtimeInfo.network.ports && task.runtimeInfo.network.ports[self.options.portIndex]) {
var req = http.request(self.healthRequestCreate(task.runtimeInfo.network.hostname, task.runtimeInfo.network.ports[self.options.portIndex]), function (res) {
if (self.options.statusCodes.indexOf(res.statusCode) > -1) {
var value = false;
if (self.options.checkBodyFunction) {
var responseBodyBuilder = '';
res.on("data", function (chunk) {
responseBodyBuilder += chunk;
});
res.on("end", function () {
value = self.options.checkBodyFunction.call(self, task, responseBodyBuilder);
self.logger.debug("Checking the response body: " + value);
if (value) {
task.runtimeInfo[self.options.propertyPrefix + "checkFailCount"] = 0;
task.runtimeInfo[self.options.propertyPrefix + "healthy"] = value;
self.setProperties(task, value);
} else {
self.setCheckFailed.call(self, task);
}
});
} else {
task.runtimeInfo[self.options.propertyPrefix + "checkFailCount"] = 0;
task.runtimeInfo[self.options.propertyPrefix + "healthy"] = true;
self.setProperties(task, true);
}
} else {
self.setCheckFailed.call(self, task);
}
res.resume();
});
req.on("error", function (error) {
self.logger.error("Error checking task health:" + JSON.stringify(error) + (self.options.propertyPrefix.length ? ", prefix: " + self.options.propertyPrefix : ""));
self.setCheckFailed.call(self, task);
});
req.end();
}
}
};
TaskHealthHelper.prototype.setProperties = function (task, value) {
var self = this;
self.options.additionalProperties.forEach(function (property) {
// If healthy or setting unhealthy
if (value || property.setUnhealthy) {
var propertyValue = value;
if (property.inverse) {
propertyValue = !value;
}
task.runtimeInfo[property.name] = propertyValue;
}
});
};
TaskHealthHelper.prototype.stopHealthCheck = function () {
var self = this;
if (self.interval) {
clearInterval(self.interval);
self.interval = null;
}
};
TaskHealthHelper.prototype.setupHealthCheck = function () {
var self = this;
self.stopHealthCheck();
self.interval = setInterval(self.checkRunningInstances, self.options.interval * 1000);
};
module.exports = TaskHealthHelper;
</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>