diff --git a/docs/Executor.html b/docs/Executor.html index dcbf7bf..70edafe 100644 --- a/docs/Executor.html +++ b/docs/Executor.html @@ -561,7 +561,7 @@
Parameters:

diff --git a/docs/Mesos.html b/docs/Mesos.html index 05a3d7b..6dd1414 100644 --- a/docs/Mesos.html +++ b/docs/Mesos.html @@ -499,7 +499,7 @@
Returns:

diff --git a/docs/Scheduler.html b/docs/Scheduler.html index ec97d8d..02fec35 100644 --- a/docs/Scheduler.html +++ b/docs/Scheduler.html @@ -349,7 +349,7 @@
Parameters:
Source:
@@ -480,7 +480,7 @@
Parameters:
Source:
@@ -634,7 +634,7 @@
Parameters:
Source:
@@ -716,7 +716,7 @@

getRun
Source:
@@ -893,7 +893,7 @@

Parameters:
Source:
@@ -1070,7 +1070,7 @@
Parameters:
Source:
@@ -1225,7 +1225,7 @@
Parameters:
Source:
@@ -1356,7 +1356,7 @@
Parameters:
Source:
@@ -1438,7 +1438,7 @@

reviveSource:
@@ -1593,7 +1593,7 @@
Parameters:
Source:
@@ -1757,7 +1757,7 @@

syncSource:
@@ -1840,7 +1840,7 @@

teardownSource:
@@ -1884,7 +1884,7 @@

teardown
- Documentation generated by JSDoc 3.4.3 on Mon Jan 16 2017 10:33:15 GMT+0100 (CET) using the Minami theme. + Documentation generated by JSDoc 3.4.3 on Tue Feb 14 2017 10:57:19 GMT-0800 (PST) using the Minami theme.
diff --git a/docs/TaskHealthHelper.html b/docs/TaskHealthHelper.html index d0abc17..69233e6 100644 --- a/docs/TaskHealthHelper.html +++ b/docs/TaskHealthHelper.html @@ -235,7 +235,7 @@
Parameters:

- Documentation generated by JSDoc 3.4.3 on Mon Jan 16 2017 10:33:16 GMT+0100 (CET) using the Minami theme. + Documentation generated by JSDoc 3.4.3 on Tue Feb 14 2017 10:57:19 GMT-0800 (PST) using the Minami theme.
diff --git a/docs/TaskHelper.html b/docs/TaskHelper.html index 4f0bc58..6300f00 100644 --- a/docs/TaskHelper.html +++ b/docs/TaskHelper.html @@ -560,7 +560,7 @@
Parameters:

- Documentation generated by JSDoc 3.4.3 on Mon Jan 16 2017 10:33:16 GMT+0100 (CET) using the Minami theme. + Documentation generated by JSDoc 3.4.3 on Tue Feb 14 2017 10:57:19 GMT-0800 (PST) using the Minami theme.
diff --git a/docs/executor.js.html b/docs/executor.js.html index 73c909b..579ae99 100644 --- a/docs/executor.js.html +++ b/docs/executor.js.html @@ -333,7 +333,7 @@

executor.js


- Documentation generated by JSDoc 3.4.3 on Mon Jan 16 2017 10:33:15 GMT+0100 (CET) using the Minami theme. + Documentation generated by JSDoc 3.4.3 on Tue Feb 14 2017 10:57:19 GMT-0800 (PST) using the Minami theme.
diff --git a/docs/index.html b/docs/index.html index 345c726..53c540e 100644 --- a/docs/index.html +++ b/docs/index.html @@ -101,7 +101,7 @@

High availability

Currently, mesos-framework doesn't sup

Sample framework implementation

See also the example implementation of a framework at mesos-framework-boilerplate.

Events

Events from Master
The following events from the leading Mesos master are exposed:

    -
  • subscribed: The first event sent by the master when the scheduler sends a SUBSCRIBE request on the persistent connection (i.e. the framework was started). Emits an object containing the frameworkId and the mesosStreamId.
  • +
  • subscribed: The first event sent by the master when the scheduler sends a SUBSCRIBE request on the persistent connection (i.e. the framework was started). Emits an object containing the frameworkId and the mesosStreamId, this may be emitted multiple times in the lifetime of a framework, as reconnections emit it as well.
  • offers: Sent by the master whenever there are new resources that can be offered to the framework. Emits the base object from the Master for this event.
  • rescind: Sent by the master when a particular offer is no longer valid. Emits the base object from the Master for this event.
  • update: Sent by the master whenever there is a status update that is generated by the executor, agent or master. Emits the base object from the Master for this event.
  • @@ -248,7 +248,25 @@

    Mesos

    The module also exposes the Mesos protocol buffer object, which "value": "my-task-id" }; -var TaskID = new (Builder.build("mesos.TaskID"))(taskId); +var TaskID = new (Builder.build("mesos.TaskID"))(taskId);

    taskHealthHelper

    This module allows for testing of task health (or any metric available via HTTP, for example cluster state, leader, etc...) and emit a scheduler event so the issue will be handled in code.

    +

    The option properties you can specify to create a taskHealthHelper are the following:

    +
      +
    • interval: The time interval between checks, in seconds, can be partial seconds (but not recommended), defaults to 30 seconds.
    • +
    • graceCount: The amount of failed checks until a task is marked as unhealthy, defaults to 4.
    • +
    • portIndex: The port index to check, defaults to 0.
    • +
    • propertyPrefix: A optional prefix for the health property, mainly to be used when having multiple health checks per framework (normal health and leader status, for instance), defaults to an empty string.
    • +
    • errorEvent: The name of the event to emit when a task fails the health check (after the grace count), defaults to propertyPrefix + "task_unhealthy".
    • +
    • additionalProperties: An array of additional properties to be set, these properties do not have the prefix added to them, information below.
    • +
    • taskNameFilter: An optional regular expression to filter tasks to be checked by the health check.
    • +
    • statusCodes: An array of acceptable HTTP status codes, defaults to [200].
    • +
    • checkBodyFunction: An optional function to check the body of the HTTP response (only after it passed the status check), parameters are the task object and the response body, needs to retrun a boolean.
    • +
    +

    The additional properties array is an array of objects with the following members:

    +
      +
    • name: The name of the property to set, for example: "leader" (mandatory).
    • +
    • setUnhealthy: Should the property be set when the check fails (optional, when unset it only sets the property when healthy).
    • +
    • inverse: Whether the health status and the property are inversed or not (optional).
    • +
    @@ -261,7 +279,7 @@

    Mesos

    The module also exposes the Mesos protocol buffer object, which

    - Documentation generated by JSDoc 3.4.3 on Mon Jan 16 2017 10:33:15 GMT+0100 (CET) using the Minami theme. + Documentation generated by JSDoc 3.4.3 on Tue Feb 14 2017 10:57:19 GMT-0800 (PST) using the Minami theme.
    diff --git a/docs/mesos.js.html b/docs/mesos.js.html index f5f825f..5835e02 100644 --- a/docs/mesos.js.html +++ b/docs/mesos.js.html @@ -99,7 +99,7 @@

    mesos.js


    - Documentation generated by JSDoc 3.4.3 on Mon Jan 16 2017 10:33:15 GMT+0100 (CET) using the Minami theme. + Documentation generated by JSDoc 3.4.3 on Tue Feb 14 2017 10:57:19 GMT-0800 (PST) using the Minami theme.
    diff --git a/docs/scheduler.js.html b/docs/scheduler.js.html index 61649b5..c383af6 100644 --- a/docs/scheduler.js.html +++ b/docs/scheduler.js.html @@ -505,11 +505,18 @@

    scheduler.js

    // Register a timeout for triggering of re-registrations of the scheduler self.httpRequest.on('socket', function (socket) { + var httpRequest = self.httpRequest; socket.setTimeout(self.options.masterConnectionTimeout); socket.on('timeout', function() { self.logger.error("Received a timeout on the long-running Master connection! Will try to re-register the framework scheduler!"); handledTimeout = true; socket.destroy(); + // Make sure the timeout is not re-emitted. + socket.setTimeout(0); + if (httpRequest !== self.httpRequest) { + self.logger.info("Already reconnected, not attempting again."); + return; + } // If we're using Mesos DNS, we can directy re-register, because Mesos DNS will discover the current leader automatically if (self.options.masterUrl === "leader.mesos") { @@ -594,7 +601,7 @@

    scheduler.js

    * @param {array} filters - The array of {@link https://github.com/apache/mesos/blob/c6e9ce16850f69fda719d4e32be3f2a2e1d80387/include/mesos/v1/mesos.proto#L1418|Filter} objects. */ Scheduler.prototype.accept = function (offers, operations, filters) { - + var self = this; // Set the Accept object @@ -946,6 +953,11 @@

    scheduler.js

    } } self.reconcileTasks = []; + self.launchedTasks.forEach(function (task) { + if (task.runtimeInfo.agentId) { + self.reconcile(task.taskId, task.runtimeInfo.agentId); + } + }); for (var i = 0; i < self.killTasks.length; i++) { self.kill(self.killTasks[i].taskId, self.killTasks[i].runtimeInfo.agentId); } @@ -968,7 +980,7 @@

    scheduler.js


    - Documentation generated by JSDoc 3.4.3 on Mon Jan 16 2017 10:33:15 GMT+0100 (CET) using the Minami theme. + Documentation generated by JSDoc 3.4.3 on Tue Feb 14 2017 10:57:19 GMT-0800 (PST) using the Minami theme.
    diff --git a/docs/taskHealthHelper.js.html b/docs/taskHealthHelper.js.html index 0d2e29d..16adc21 100644 --- a/docs/taskHealthHelper.js.html +++ b/docs/taskHealthHelper.js.html @@ -61,11 +61,13 @@

    taskHealthHelper.js

    self.options.interval = options.interval || 30; self.options.graceCount = options.graceCount || 4; self.options.portIndex = options.portIndex || 0; - self.options.errorEvent = options.errorEvent || "task_unhealthy"; + 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.propertyPrefix = options.propertyPrefix || ""; + self.options.checkBodyFunction = options.checkBodyFunction || null; + if (options.url) { self.options.url = options.url; } else { @@ -112,21 +114,14 @@

    taskHealthHelper.js

    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.options.additionalProperties.forEach(function (property) { - if (property.setUnhealthy) { - var value = false; - if (property.inverse) { - value = !value; - } - task.runtimeInfo[property.name] = value; - } - }); + 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; @@ -135,15 +130,35 @@

    taskHealthHelper.js

    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) { - task.runtimeInfo[self.options.propertyPrefix + "checkFailCount"] = 0; - task.runtimeInfo[self.options.propertyPrefix + "healthy"] = true; - self.options.additionalProperties.forEach(function (property) { - var value = true; - if (property.inverse) { - value = !value; - } - task.runtimeInfo[property.name] = value; - }); + + 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); + task.runtimeInfo[self.options.propertyPrefix + "healthy"] = value; + self.logger.debug("Checking the response body: " + value); + + if (value) { + task.runtimeInfo[self.options.propertyPrefix + "checkFailCount"] = 0; + 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); } @@ -158,6 +173,22 @@

    taskHealthHelper.js

    } }; +TaskHealthHelper.prototype.setProperties = function (task, value) { + var self = this; + self.options.additionalProperties.forEach(function (property) { + //self.logger.debug("Setting " + property.name + " to " + value); + + // 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; @@ -170,6 +201,7 @@

    taskHealthHelper.js

    TaskHealthHelper.prototype.setupHealthCheck = function () { var self = this; + self.stopHealthCheck(); self.interval = setInterval(self.checkRunningInstances, self.options.interval * 1000); }; @@ -186,7 +218,7 @@

    taskHealthHelper.js


    - Documentation generated by JSDoc 3.4.3 on Mon Jan 16 2017 10:33:15 GMT+0100 (CET) using the Minami theme. + Documentation generated by JSDoc 3.4.3 on Tue Feb 14 2017 10:57:19 GMT-0800 (PST) using the Minami theme.
    diff --git a/docs/taskHelper.js.html b/docs/taskHelper.js.html index 50104d5..c3714fa 100644 --- a/docs/taskHelper.js.html +++ b/docs/taskHelper.js.html @@ -175,7 +175,7 @@

    taskHelper.js


    - Documentation generated by JSDoc 3.4.3 on Mon Jan 16 2017 10:33:15 GMT+0100 (CET) using the Minami theme. + Documentation generated by JSDoc 3.4.3 on Tue Feb 14 2017 10:57:19 GMT-0800 (PST) using the Minami theme.