diff --git a/coffee/event-poller.coffee b/coffee/event-poller.coffee index 99b4ee5..9ef67c2 100644 --- a/coffee/event-poller.coffee +++ b/coffee/event-poller.coffee @@ -32,8 +32,14 @@ log = logger.getLogger logconf log.info 'EP | Event Poller starts up' process.on 'uncaughtException', ( err ) -> - log.error 'Probably one of the event pollers created an error in a callback function!' - log.error err + # TODO we'd have to wrap the dynamic-modules module in an own child process which + # we could let crash, create log info about what dynamic module caused the crash and + # then restart the dynamic-modules module, passing the crash info to the logger of the + # rule that caused this issue. on the other hand we're just fine like this since only + # the deferred token of the corresponding rule gets eliminated if it throws an error + # and the event polling won't continue fo this rule, which is fine for us, except that + # we do not have a good way to inform the user about his error. + log.error 'Probably one of the event pollers produced an error!' # Initialize required modules (should be in cache already) db logger: log @@ -174,6 +180,7 @@ This function will loop infinitely every 10 seconds until isRunning is set to fa pollLoop = () -> # We only loop if we're running if isRunning + #FIXME CHECK IF ALREADY RUNNING! #FIXME a scheduler should go here because we are limited in setTimeout # to an integer value -> ~24 days at maximum! diff --git a/coffee/persistence.coffee b/coffee/persistence.coffee index 9db798f..49380b1 100644 --- a/coffee/persistence.coffee +++ b/coffee/persistence.coffee @@ -347,14 +347,17 @@ class IndexedModules @db.smembers "#{ @setname }:#{ userId }:#{ ruleId }:#{ mId }:functions", ( err, obj ) => sem = obj.length oAnswer = {} - for func in obj - fRegisterFunction = ( func ) => - ( err, obj ) => - if obj - oAnswer[ func ] = obj - if --sem is 0 - cb null, oAnswer - @db.get "#{ @setname }:#{ userId }:#{ ruleId }:#{ mId }:function:#{ func }", fRegisterFunction func + if sem is 0 + cb null, oAnswer + else + for func in obj + fRegisterFunction = ( func ) => + ( err, obj ) => + if obj + oAnswer[ func ] = obj + if --sem is 0 + cb null, oAnswer + @db.get "#{ @setname }:#{ userId }:#{ ruleId }:#{ mId }:function:#{ func }", fRegisterFunction func getUserArguments: ( userId, ruleId, mId, funcId, cb ) => @log.info "DB | (IdxedMods) #{ @setname }.getUserArguments( #{ userId }, #{ ruleId }, #{ mId }, #{ funcId } )" @@ -596,14 +599,14 @@ exports.getAllActivatedRuleIdsPerUser = ( cb ) => cb null, result else semaphore = obj.length - fFetchActiveUserRules = ( userId ) => - @db.smembers "user:#{ user }:active-rules", ( err, obj ) => - if obj.length > 0 - result[userId] = obj - if --semaphore is 0 - cb null, result - fFetchActiveUserRules user for user in obj - + for user in obj + fProcessAnswer = ( user ) -> + ( err, obj ) => + if obj.length > 0 + result[user] = obj + if --semaphore is 0 + cb null, result + @db.smembers "user:#{ user }:active-rules", fProcessAnswer user ### ## Users diff --git a/examples/action-invokers/converter.coffee b/examples/action-invokers/converter.coffee index 16f73b4..2f686d3 100644 --- a/examples/action-invokers/converter.coffee +++ b/examples/action-invokers/converter.coffee @@ -6,7 +6,7 @@ exports.parseTextToJSON = ( eventname, text ) -> try pushEvent - event: eventname + eventname: eventname body: JSON.parse text log "Text successfully parsed" catch e @@ -16,7 +16,7 @@ exports.parseTextToJSON = ( eventname, text ) -> # Parses objects to text exports.parseObjectToPrettyText = ( eventname, obj ) -> pushEvent - event: eventname + eventname: eventname body: JSON.stringify text, undefined, 2 @@ -30,7 +30,7 @@ exports.accumulateEvents = ( evtname, evt, sendTime ) -> if lastSend < yesterday lastSend = sTime pushEvent - event: evtname + eventname: evtname body: arrEvents arrEvents = [] @@ -56,7 +56,7 @@ fPushEvent = () -> if eventname isnt '' log "Pushing changed interval event" pushEvent - event: eventname + eventname: eventname body: event setTimeout fPushEvent, interval @@ -109,7 +109,7 @@ exports.LongLatToMeterDistance = ( latOne, longOne, latTwo, longTwo, eventname ) c = 2 * Math.atan2 Math.sqrt( a ), Math.sqrt 1 - a pushEvent - event: eventname + eventname: eventname body: latOne: latOne longOne: longOne diff --git a/examples/action-invokers/neospeech.coffee b/examples/action-invokers/neospeech.coffee index 3b75fc6..5126d66 100644 --- a/examples/action-invokers/neospeech.coffee +++ b/examples/action-invokers/neospeech.coffee @@ -101,7 +101,7 @@ pollUntilDone = ( conversionNumber, email, accountid, infoEvent ) -> if oAnsw.resultCode is '0' if oAnsw.statusCode is '4' or oAnsw.statusCode is '5' pushEvent - event: infoEvent + eventname: infoEvent body: accountid: accountid downloadUrl: oAnsw.downloadUrl diff --git a/js/event-poller.js b/js/event-poller.js index fdab541..71f80b7 100644 --- a/js/event-poller.js +++ b/js/event-poller.js @@ -40,8 +40,7 @@ Dynamic Modules log.info('EP | Event Poller starts up'); process.on('uncaughtException', function(err) { - log.error('Probably one of the event pollers created an error in a callback function!'); - return log.error(err); + return log.error('Probably one of the event pollers produced an error!'); }); db({ diff --git a/js/persistence.js b/js/persistence.js index 2799d52..88cb414 100644 --- a/js/persistence.js +++ b/js/persistence.js @@ -404,22 +404,26 @@ Persistence var fRegisterFunction, func, oAnswer, sem, _i, _len, _results; sem = obj.length; oAnswer = {}; - _results = []; - for (_i = 0, _len = obj.length; _i < _len; _i++) { - func = obj[_i]; - fRegisterFunction = function(func) { - return function(err, obj) { - if (obj) { - oAnswer[func] = obj; - } - if (--sem === 0) { - return cb(null, oAnswer); - } + if (sem === 0) { + return cb(null, oAnswer); + } else { + _results = []; + for (_i = 0, _len = obj.length; _i < _len; _i++) { + func = obj[_i]; + fRegisterFunction = function(func) { + return function(err, obj) { + if (obj) { + oAnswer[func] = obj; + } + if (--sem === 0) { + return cb(null, oAnswer); + } + }; }; - }; - _results.push(_this.db.get("" + _this.setname + ":" + userId + ":" + ruleId + ":" + mId + ":function:" + func, fRegisterFunction(func))); + _results.push(_this.db.get("" + _this.setname + ":" + userId + ":" + ruleId + ":" + mId + ":function:" + func, fRegisterFunction(func))); + } + return _results; } - return _results; }; })(this)); }; @@ -751,26 +755,28 @@ Persistence return function(cb) { _this.log.info("DB | Fetching all active rules"); return _this.db.smembers('users', function(err, obj) { - var fFetchActiveUserRules, result, semaphore, user, _i, _len, _results; + var fProcessAnswer, result, semaphore, user, _i, _len, _results; result = {}; if (obj.length === 0) { return cb(null, result); } else { semaphore = obj.length; - fFetchActiveUserRules = function(userId) { - return _this.db.smembers("user:" + user + ":active-rules", function(err, obj) { - if (obj.length > 0) { - result[userId] = obj; - } - if (--semaphore === 0) { - return cb(null, result); - } - }); - }; _results = []; for (_i = 0, _len = obj.length; _i < _len; _i++) { user = obj[_i]; - _results.push(fFetchActiveUserRules(user)); + fProcessAnswer = function(user) { + return (function(_this) { + return function(err, obj) { + if (obj.length > 0) { + result[user] = obj; + } + if (--semaphore === 0) { + return cb(null, result); + } + }; + })(this); + }; + _results.push(_this.db.smembers("user:" + user + ":active-rules", fProcessAnswer(user))); } return _results; } diff --git a/package.json b/package.json index 8c6d253..cc2475c 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "bunyan": "0.22.1", - "coffee-script": "1.6.3", + "coffee-script": "1.7.1", "crypto-js": "3.1.2", "express": "3.4.8", "groc": "0.6.1", @@ -18,7 +18,7 @@ "js-select": "0.6.0", "mustache": "0.8.1", "needle": "0.6.3", - "nodeunit": "0.8.4", + "nodeunit": "0.8.6", "redis": "0.10.0", "request": "2.33.0", "optimist": "0.6.1" diff --git a/unit_tests.sh b/unit_tests.sh index ffded78..6deb78f 100755 --- a/unit_tests.sh +++ b/unit_tests.sh @@ -4,6 +4,7 @@ var fs = require( 'fs' ), path = require( 'path' ), nodeunit = require( 'nodeunit' ), db = require( './js/persistence' ), + cs = require('coffee-script'), args = process.argv.slice( 2 ), fEnd = function() { console.log( 'Shutting down DB from unit_test.sh script. ' @@ -11,6 +12,9 @@ var fs = require( 'fs' ), db.shutDown(); }; +if (cs.register) { + cs.register(); +} if( args[ 0 ] !== undefined ) { var fl = path.resolve( args[ 0 ] ); if ( fs.existsSync( fl ) ) { diff --git a/webpages/handlers/coffee/forge_rule.coffee b/webpages/handlers/coffee/forge_rule.coffee index d0de8c2..52ea5df 100644 --- a/webpages/handlers/coffee/forge_rule.coffee +++ b/webpages/handlers/coffee/forge_rule.coffee @@ -54,7 +54,7 @@ domSectionSelectedActions.append $( '
| ' ).text( ' : ' ).append inp
table.append tr
if i > 0
- $( '#event_poller_params' ).html 'Required Global Parameters:'
+ $( '#event_poller_params' ).html 'Required User-specific Data:'
$( '#event_poller_params' ).append table
fFillEventParams id
@@ -286,7 +286,7 @@ fFetchEventFunctionArgs = ( arrName ) ->
oParams = JSON.parse data.message
if oParams[ arrName[ 1 ] ]
if oParams[ arrName[ 1 ] ].length > 0
- $( '#event_poller_params' ).append $( "" ).text 'Required Function Parameters:'
+ $( '#event_poller_params' ).append $( "" ).text 'Required Rule-specific Data:'
table = $( ' |