UNPKG

waffle

Version:

シンプルなWEBアプリケーションフレームワークです。(ALL YOUR NODE ARE BELONG TO US)

136 lines (117 loc) 3.85 kB
/* * Copyright 2012 Katsunori Koyanagi * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ /** * @overview アプリケーションのクラスタリング機能を提供するアドオンです。 * 処理の分散化及び、異常終了やタイムアウトした子プロセスの再起動をサポートします。 */ "use strict"; var cluster = require("cluster"); var app = require("../Waffle"); function WorkerManager(options) { var workers = {}; function checkChildProcesses() { var now = process.uptime(); var timeout = options.timeout / 1000; for ( var pid in workers) { var worker = workers[pid]; if (now - worker.__heartbeat__ > timeout) { app.log.error("worker %d timeouted.", worker.pid); worker.kill(); } } setTimeout(checkChildProcesses, options.watch); } function createWorker() { var worker = cluster.fork(); workers[worker.pid] = worker; worker.__heartbeat__ = process.uptime(); worker.on("message", function(msg) { if (msg === "heartbeat") { worker.__heartbeat__ = process.uptime(); } }); app.log("worker %d created.", worker.pid); } this.start = function() { for ( var i = 0; i < options.forks; i++) { createWorker(); } cluster.on("death", function(worker) { delete workers[worker.pid]; app.log.error("worker %d died.", worker.pid); createWorker(); }); checkChildProcesses(); } }; /** * クラスタを開始します。 * <p> * オプションは以下のように定義することができますが、省略することも可能です。 * </p> * <table> * <tr> * <th>forks</th> * <td>プロセスのフォーク数、省略時はOSが認識するCPU数が使用される</td> * </tr> * <tr> * <th>timeout</th> * <td>ワーカの実行がタイムアウトするまでのミリ秒の時間、省略時は3000ミリ秒</td> * </tr> * <tr> * <th>heartbeat</th> * <td>ワーカが生存中であることをマスタへ通知する間隔(ミリ秒)、省略時は1000ミリ秒</td> * </tr> * <tr> * <th>watch</th> * <td>ワーカが生存中であることをチェックする間隔(ミリ秒)、省略時は1000ミリ秒</td> * </tr> * </table> * * @example <code> * var waffle = require("waffle"); * waffle.extensions.cluster(function(){ * waffle.start("foo/bar.json"); * }); * </code> * @function * @name Extensions#cluster * @param {Function} * callback ワーカとしてプロセスが起動した場合に呼ばれるコールバック関数 * @param {Object} * options クラスタの管理に使用されるオプションのオブジェクト(省略可) * */ module.exports = function(callback, options) { options = options || {}; function setNumber(name, defaultValue) { var num = parseInt(options[name], 10); if (isNaN(num) || num < 1) { num = defaultValue; } options[name] = num; } setNumber("forks", require("os").cpus().length); setNumber("timeout", 3000); setNumber("heartbeat", 1000); setNumber("watch", 1000); if (cluster.isMaster) { new WorkerManager(options).start(); return; } setInterval(process.send, options.heartbeat, "heartbeat"); callback(); };