Permalink
Browse files

0.3.0 Node God as four processes, rotates log on size and time, Licen…

…se, ChangeLog
  • Loading branch information...
haraldrudell committed Jan 21, 2013
1 parent 047dbf4 commit 954f5e17ee6ce6a98ed7fac943f1318805719e04
View
@@ -0,0 +1,19 @@
+2013-01-20 0.3.0 Node God as four processes, rotates log on size and time, License, ChangeLog
+2013-01-14 0.2.3 one-line top-level files, nodegodweb api rewrote godmodel, apprunner 0.2.2
+2013-01-12 0.2.2 refactored perioder, rotatedlogger with rename-retry
+2013-01-12 0.2.1 pidlink with retry, test pass
+2013-01-10 0.2.0 resilitient master process architecture change
+2013-01-02 0.1.4 master using socket server. ui can now recycle with apps running
+2012-12-29 0.1.3 support haraldutill 0.1.4
+2012-12-25 0.1.2 refactor master process, tests
+2012-12-22 0.1.1 recovery now continuous, log uses getISOPacific
+2012-12-22 0.1.0 master process and ipc
+2012-09-20 0.0.11 force kill printout
+2012-09-14 0.0.10 top-color red on lost connection, loggin of changes only
+2012-09-11 0.0.9 sigint sigusr2 better watchdelay warning coloring apprunner
+2012-09-10 0.0.8 shutdown with SIGINT then kill
+2012-09-03 0.0.7 Watch events update watcher files, watchCopy, haraldutil 0.1.5
+2012-07-23 0.0.6: support haraldops 0.1.1
+2012-07-02 0.0.5 better comms and updates
+2012-06-23 0.0.4 Fixed file watchers
+2012-05-27 v 0.0.1 back to express 2, sockets in appFile loading
View
@@ -0,0 +1,9 @@
+Copyright © Harald Rudell 2011 MIT License
+
+The MIT License (MIT)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
28 app.js
@@ -1,13 +1,21 @@
// app.js
// Nodegod manages apps
-// © Harald Rudell 2012
+// © Harald Rudell 2012 MIT License
-var appIdentifier = 'nodegodmaster'
-require('./lib/master/nodegodmaster').run({
- port: 1113,
- interface: '127.0.0.1',
- ignoredSignals: ['SIGINT', 'SIGUSR2', 'SIGHUP'],
- appIdentifier: appIdentifier,
- launchArray: ['node', require('path').join(__dirname, 'webprocess')],
- fsLogArray: ['node', require('path').join(__dirname, 'logprocess'), appIdentifier],
-})
+require('apprunner').initApp(require('haraldops').init({
+ appName: 'Node God',
+ noFile: true, // haraldops: don't load a settings file
+ noInfoLog: true, // appinit quiet
+ logger: function () {}, // haraldops quiet
+ api: {
+ apiMap: {
+ masterlauncher: {
+ onLoad: true,
+ spawn: {
+ file: 'node',
+ args: [require('path').join(__dirname, 'masterprocess')],
+ }
+ }
+ }
+ }
+}))
View
@@ -1,5 +1,6 @@
// appentity.js
-// © Harald Rudell 2012
+// Manage data for one app
+// © Harald Rudell 2012 MIT License
var require = require('apprunner').getRequire(require)
var pidlink = require('./pidlink')
View
@@ -1,6 +1,6 @@
// appstate.js
// manage one app through the master process
-// © Harald Rudell 2012
+// © Harald Rudell 2012 MIT License
var masterlink = require('./masterlink')
View
@@ -0,0 +1,121 @@
+// childipc.js
+// Write ipc to a child process
+// © Harald Rudell 2013 <harald@therudells.com> MIT License
+
+// http://nodejs.org/api/util.html
+var util = require('util')
+// http://nodejs.org/api/stream.html
+var stream = require('stream')
+
+exports.ChildIpc = ChildIpc
+
+/*
+ipc write stream for child
+if this.writable ipc is available
+will emit drain, close and errors
+final event is close or error
+*/
+function ChildIpc() {
+ var self = this
+ stream.Stream.call(this)
+ this.writable
+ this.write = write
+ this.end = end
+ this.destroy = destroy
+ var didEmitError
+ var isConnected
+
+ if (process.send) { // process.once does not return process...
+ process.on('error', processErrorListener)
+ .once('disconnect', processDisconnectListener)
+ isConnected = true
+ this.writable = true
+ }
+
+ // write(message, handle, cb)
+ function write(message, handle) {
+ var result = false
+ var err
+ var args = Array.prototype.slice.call(arguments)
+ var cb = typeof args[args.length - 1] === 'function' ? args.pop() : null
+ if (args.length > 1 && typeof handle === 'string') err = new Error('write handle argument cannot be string')
+ else if (!self.writable) err = new Error('ipc not available')
+ else {
+ try {
+ result = process.send.apply(process, args)
+ } catch (e) {
+ err = e
+ }
+ if (!err) self.emit('drain')
+ }
+ if (err) internalDestroy(cb, [err])
+ else if (cb) {
+ var cbArgs = []
+ if (err) cbArgs.push(err)
+ cb.apply(this, cbArgs)
+ }
+ return result
+ }
+
+ // end(message, handle, cb)
+ function end() {
+ var err
+ var args = Array.prototype.slice.call(arguments)
+ var cb = typeof args[args.length - 1] === 'function' ? args.pop() : null
+ if (self.writable && args.length) write.apply(this, args.concat(afterWrite))
+ else afterWrite()
+
+ function afterWrite(e) {
+ if (e) err = e
+ destroy(afterDestroy)
+ }
+
+ function afterDestroy(e) {
+ if (e && !err) err = e
+ if (cb) {
+ var cbArgs = []
+ if (err) cbArgs.push(err)
+ cb.apply(this, cbArgs)
+ }
+ }
+ }
+
+ function destroy(cb) {
+ internalDestroy(cb)
+ }
+
+ /*
+ cb(err) optional funciton
+ args: array of values, first may be instanceof Error
+ */
+ function internalDestroy(cb, args) {
+ var isError = Array.isArray(args) && args[0] instanceof Error
+ if (self.writable) {
+ self.writable = false
+ if (isConnected) {
+ isConnected = false
+ process.disconnect()
+ process.removeListener('disconnect', processDisconnectListener)
+ }
+ process.removeListener('error', processErrorListener)
+ if (!isError) self.emit('close')
+ }
+ if (isError) self.emit.apply(self, ['error'].concat(args))
+ if (cb) {
+ var cbArgs = []
+ if (isError) cbArgs.push(args[0])
+ cb.apply(this, cbArgs)
+ }
+ }
+
+ function processDisconnectListener() {
+ isConnected = false
+ internalDestroy()
+ }
+ function processErrorListener() {
+ var args = Array.prototype.slice.call(arguments)
+ if (!(args[0] instanceof Error)) args.unshift(new Error('process error'))
+ internalDestroy(null, args)
+ }
+}
+util.inherits(ChildIpc, stream.Stream)
View
@@ -2,14 +2,17 @@
// Log stdin to rotatedlogger
// © Harald Rudell 2013 MIT License
-// http://nodejs.org/api/util.html
-var util = require('util')
-
require = require('apprunner').getRequire(require, exports, {
api: require('apprunner').getAppData().appName, initApi: initApi,
ready: false})
var rotatedlogger = require('./rotatedlogger')
+// http://nodejs.org/api/util.html
+var util = require('util')
+// https://github.com/haraldrudell/apprunner
+var apprunner = require('apprunner')
+
+var log = console.log
/*
Write stdin to a rotated log
@@ -19,14 +22,56 @@ opts: object
*/
function initApi(opts) {
var logMarker = require.emitter.id + ':' + process.pid
- var logger = new rotatedlogger.RotatedLog({stdout: false, file: true, streamOpts: {logFile: opts.logName}})
+ log = function () {
+ console.log(logMarker, util.format.apply(this, Array.prototype.slice.call(arguments)))
+ }
+ var logger
+
+ if (Array.isArray(opts.ignoredSignals)) opts.ignoredSignals.forEach(function (signal) {
+ process.on(signal, getSignalHandler(signal))
+ })
+
+
+ if (process.send) {
+ logger = new rotatedlogger.RotatedLog({stdout: false, file: true, streamOpts: {logFile: opts.logName}})
- process.stdin.on('data', echoData) // returns this
- process.stdin.setEncoding('utf-8') // returns undefined
- process.stdin.resume()
- if (process.send) process.send('ok')
+ process.stdin.setEncoding('utf-8') // returns undefined
+ process.stdin.on('data', stdinDataListener) // returns this
+ .once('close', stdinCloseListener)
+ .resume()
+ process.send('ok') // let parent know we are ready
+ } else {
+ log('Fatal: ipc not available')
+ shutdown()
+ }
- function echoData(data) {
+ function stdinDataListener(data) {
logger.write(data)
}
+ function stdinCloseListener() {
+ log('Detected pipe close')
+ logger.write('Log pipe close event ' + (new Date).toISOString())
+ logger.close(cleanup)
+ }
+
+ function cleanup(err) {
+ if (err) log('logger.close:', err)
+ process.stdin.removeListener('data', stdinDataListener)
+ process.stdin.removeListener('close', stdinCloseListener)
+ process.stdin.pause()
+ logger = null
+ shutdown()
+ }
+
+ function shutdown() {
+ apprunner.shutdown()
+ }
+}
+
+function getSignalHandler(signal) {
+ return notifySignal
+
+ function notifySignal() {
+ log('Ignoring signal:', signal)
+ }
}
View
@@ -1,5 +1,6 @@
// getfilenames.js
// build an array of filenames from a single entry or an array of file and folder names
+// © Harald Rudell 2011 <harald@therudells.com> MIT License
// http://nodejs.org/docs/latest/api/fs.html
var fs = require('fs')
View
@@ -1,4 +1,7 @@
-// nodereq.js
+// godcontrol.js
+// Controller for Node God
+// © Harald Rudell 2011 MIT License
+
var godmodel = require('./godmodel')
var appentity = require('./appentity')
var godsocket = require('./godsocket')
View
@@ -1,6 +1,6 @@
// godmodel.js
// Execute on configuration files
-// © Harald Rudell 2012
+// © Harald Rudell 2012 MIT License
require = require('apprunner').getRequire(require)
@@ -82,7 +82,7 @@ function loadParentData(cb) {
result = data.appMap
end(true)
}
- if (data.launchTime && typeof data.launchTime == 'number') require('../routes/godview').setTitle(undefined, data.launchTime)
+ if (data.launchTime && typeof data.launchTime == 'number') require('./routes/godview').setTitle(undefined, data.launchTime)
}
function end(isMessage) {
View
@@ -1,5 +1,6 @@
// godsocket.js
-// socket layer for nodegod
+// Server-side socket layer for Node Fod
+// © Harald Rudell 2011 MIT License
// imports
var socketio = require('socket.io')
View
@@ -0,0 +1,33 @@
+// listenermanager.js
+// Manage event listeners for various events.EventEmitters
+// © Harald Rudell 2013 <harald@therudells.com> MIT License
+
+exports.ListenerManager = ListenerManager
+
+function ListenerManager() {
+ var listeners = []
+ this.addListener = addListener
+ this.removeListeners = removeListeners
+
+ /*
+ object: events.EventEmitter
+ fName: string: the function name to use 'on' or 'once'
+ event: string: the event name eg. 'exit'
+ listener: function: the event listener
+ */
+ function addListener(object, fName, event, listener) {
+ listeners.push({
+ object: object[fName](event, listener),
+ event: event,
+ listener: listener,
+ })
+ }
+
+ function removeListeners() {
+ var list = listeners
+ listeners = []
+ list.forEach(function (o) {
+ o.object.removeListener(o.event, o.listener)
+ })
+ }
+}
View
@@ -1,6 +1,6 @@
// appconduit.js
// manage a child process for the ui
-// © Harald Rudell 2012
+// © Harald Rudell 2012 MIT License
var streamlabeller = require('./streamlabeller')
Oops, something went wrong.

0 comments on commit 954f5e1

Please sign in to comment.