diff --git a/Gruntfile.coffee b/Gruntfile.coffee index b7de2af..f1cb841 100644 --- a/Gruntfile.coffee +++ b/Gruntfile.coffee @@ -36,7 +36,8 @@ module.exports = (grunt) -> options: require: [ "should" ] reporter: "spec" - bail: false + bail: ( if process.env.BAIL then true else false ) + grep: process.env.GREP timeout: 3000 slow: 3 @@ -89,3 +90,4 @@ module.exports = (grunt) -> # build the project grunt.registerTask "build", [ "clear", "coffee:base", "includereplace" ] grunt.registerTask "build-dev", [ "clear", "coffee:base", "docs", "test" ] + diff --git a/README.md b/README.md index 24f7630..b44ced4 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,28 @@ Stop the worker and close the connection. After this it's no longer possible to reuse the worker-instance. It's just intended to kill all timers and connections so your script will end. +### `.info( cb )` + +Get the current queue attributes. +This is just a shortcut to the [`rsmq.getQueueAttributes`](https://github.com/smrchy/rsmq#getqueueattributes). + +**Arguments** + +* `cb` : *( `Function` )*: Callback with `( err, attributes )`. See [rsmq-docs](https://github.com/smrchy/rsmq#getqueueattributes) for details. + +### `.size( [hidden=false], cb )` + +Get the current queue size. + +**Arguments** + +* `hidden` : *( `Boolean` optional; default = `false` )*: The count of messages including the currently hidden/"in flight" messages. +* `cb` : *( `Function` optional )*: Callback with `( err, size )`. The `size` is a `Number` and repersents the number of messages in the queue. If `hidden=true` you will receive the numebr of currently hidden messages + +**Return** + +*( Self )*: The instance itself for chaining. + ## Events ### `message` @@ -309,6 +331,7 @@ This is an advanced example showing some features in action. ## Release History |Version|Date|Description| |:--:|:--:|:--| +|0.5.0|2016-07-14|Added methods `.info(cb)` ([Issue#17](https://github.com/mpneuried/rsmq-worker/issues/17)) and `.size( [hidden,] cb )`| |0.4.3|2016-06-20|Optimized event listeners [Issue#15](https://github.com/mpneuried/rsmq-worker/issues/15). Thanks to [Kevin Turner](https://github.com/kpturner )| |0.4.2|2016-05-06|Added the `.quit()` function [Issue#11](https://github.com/mpneuried/rsmq-worker/issues/11). Thanks to [Sam Fung](https://github.com/5amfung )| |0.4.1|2016-04-05|Fixed missing isNumber function| diff --git a/_src/lib/rsmq-worker.coffee b/_src/lib/rsmq-worker.coffee index 0e2ed95..8654cc2 100644 --- a/_src/lib/rsmq-worker.coffee +++ b/_src/lib/rsmq-worker.coffee @@ -220,7 +220,58 @@ class RSMQWorker extends require( "mpbasic" )() changeInterval: ( interval )=> @config.interval = interval return @ + + ### + ## info + + `RSMQWorker.info( cb )` + + Get the queue attributes + @param { Function } cb The callback function + + @return { RSMQWorker } The instance itself for chaining. + + @api public + ### + info: ( cb )=> + @queue.getQueueAttributes qname: @queuename, ( err, resp )=> + if err + @error "queue info", err + cb( err ) + return + cb( null, resp ) + return + return @ + + ### + ## size + + `RSMQWorker.size( hidden, cb )` + + Get the queue size. + + @param { Boolean } [hidden=false] Get the message count of the queue including the currently hidden/"in flight" messages. + @param { Function } cb The callback function + + @return { RSMQWorker } The instance itself for chaining. + + @api public + ### + size: ( [hidden]..., cb )=> + @queue.getQueueAttributes qname: @queuename, ( err, resp )=> + if err + @error "queue size", err + cb( err ) + return + + _size = resp?.msgs or 0 + if hidden is true + _size = resp.hiddenmsgs or 0 + cb( null, _size ) + return + return @ + ### ## _initRSMQ diff --git a/_src/test/main.coffee b/_src/test/main.coffee index 93e875d..91548df 100644 --- a/_src/test/main.coffee +++ b/_src/test/main.coffee @@ -1,8 +1,10 @@ should = require( 'should' ) -utils = require( './utils' ) +rand = require( 'randoms' ) +async = require( 'async' ) -_queuename = utils.randomString( 10, 1 ) +_queuename = rand.string( 10, 1 ) worker = null +_created = null describe "----- rsmq-worker TESTS -----", -> @@ -10,7 +12,7 @@ describe "----- rsmq-worker TESTS -----", -> RSMQWorker = require( "../." ) worker = new RSMQWorker( _queuename, { interval: [ 0, 1, 5 ] } ) - + _created = Math.round( Date.now() / 1000 ) worker.on "ready", -> done() return @@ -25,7 +27,7 @@ describe "----- rsmq-worker TESTS -----", -> return describe 'Main Tests', -> - + _tRecv = 0 # Implement tests cases here it "check interval config", ( done )-> worker.config.interval.length.should.equal( 3 ) @@ -37,7 +39,7 @@ describe "----- rsmq-worker TESTS -----", -> # Implement tests cases here it "first test", ( done )-> - _examplemsg = utils.randomString( utils.randRange( 4, 99 ), 3 ) + _examplemsg = rand.string( rand.number( 4, 99 ), 3 ) _testFn = ( msg, next, id )-> @@ -52,10 +54,11 @@ describe "----- rsmq-worker TESTS -----", -> worker.send( _examplemsg ) + _tRecv++ return it "delay test", ( done )-> - _examplemsg = utils.randomString( utils.randRange( 4, 99 ), 3 ) + _examplemsg = rand.string( rand.number( 4, 99 ), 3 ) _start = Date.now() _delay = 5 @timeout( _delay*1.5*1000 ) @@ -72,10 +75,11 @@ describe "----- rsmq-worker TESTS -----", -> worker.on( "message", _testFn ) worker.send( _examplemsg, _delay ) + _tRecv++ return it "delay test with callback", ( done )-> - _examplemsg = utils.randomString( utils.randRange( 4, 99 ), 3 ) + _examplemsg = rand.string( rand.number( 4, 99 ), 3 ) _start = Date.now() _delay = 5 @timeout( _delay*1.5*1000 ) @@ -91,13 +95,145 @@ describe "----- rsmq-worker TESTS -----", -> worker.on( "message", _testFn ) + _tRecv++ worker.send _examplemsg, _delay, ( err )-> should.not.exist( err ) return return + it "test size method", ( done )-> + @timeout( 15000 ) + _COUNT = 10 + _examplemsgs = [] + for _x in [1.._COUNT] + _examplemsgs.push rand.string( rand.number( 4, 99 ), 3 ) + + _runHiddenSize = ( next )-> + return -> + # check hidden size and go on + worker.size true, ( err, size )-> + throw err if err + should.exist( size ) + size.should.be.a.number + size.should.equal( 1 ) + _idx++ + next() + worker.start() + return + return + + _idx = 0 + _testFn = ( msg, next, id )-> + should.equal( msg, _examplemsgs[ _idx ] ) + + if _idx is 0 + # stop and wait to check the hidden size + setTimeout( _runHiddenSize( next ), 1000 ) + worker.stop() + return + + next() + + _idx++ + # done if all messages are received + if _idx >= _COUNT + worker.removeListener( "message", _testFn ) + done() + return + + worker.on( "message", _testFn ) + + worker.stop() + + _fnSend = ( msg, cba )-> + _tRecv++ + worker.send( msg, 0, cba ) + return + + async.every _examplemsgs, _fnSend, ( err )-> + throw err if err + + worker.size ( err, size )-> + worker.start() # start immediate so the following tests will not fail due to a stopped worker + + throw err if err + should.exist( size ) + size.should.be.a.number + size.should.equal( _COUNT ) + + return + return + return + + it "test info method", ( done )-> + @timeout( 15000 ) + _COUNT = 10 + _examplemsgs = [] + for _x in [1.._COUNT] + _examplemsgs.push rand.string( rand.number( 4, 99 ), 3 ) + + _idx = 0 + _testFn = ( msg, next, id )-> + should.equal( msg, _examplemsgs[ _idx ] ) + + next() + + _idx++ + # done if all messages are received + if _idx >= _COUNT + worker.removeListener( "message", _testFn ) + done() + return + + worker.on( "message", _testFn ) + + worker.stop() + + _fnSend = ( msg, cba )-> + _tRecv++ + worker.send( msg, 0, cba ) + return + + async.every _examplemsgs, _fnSend, ( err )-> + throw err if err + + worker.info ( err, info )-> + worker.start() # start immediate so the following tests will not fail due to a stopped worker + + throw err if err + should.exist( info ) + info.should.have.property( "msgs" ) + .with.equal( _COUNT ) + + info.should.have.property( "delay" ) + .with.equal( 0 ) + + info.should.have.property( "vt" ) + .with.equal( 30 ) + + info.should.have.property( "maxsize" ) + .with.equal( 65536 ) + + info.should.have.property( "totalsent" ) + .with.equal( _tRecv ) + + info.should.have.property( "totalrecv" ) + .with.equal( _tRecv - _COUNT ) + + info.should.have.property( "created" ) + .with.approximately( _created, 10 ) + + info.should.have.property( "modified" ) + .with.approximately( _created, 10 ) + + + + return + return + return + it "error throw within message processing - Issue #3 (A)", ( done )-> - _examplemsg = utils.randomString( utils.randRange( 4, 99 ), 3 ) + _examplemsg = rand.string( rand.number( 4, 99 ), 3 ) @timeout( 3000 ) _testFn = ( msg, next, id )-> @@ -125,7 +261,7 @@ describe "----- rsmq-worker TESTS -----", -> return it "code error within message processing - Issue #3 (B)", ( done )-> - _examplemsg = utils.randomString( utils.randRange( 4, 99 ), 3 ) + _examplemsg = rand.string( rand.number( 4, 99 ), 3 ) @timeout( 3000 ) _testFn = ( msg, next, id )-> @@ -156,9 +292,9 @@ describe "----- rsmq-worker TESTS -----", -> return return - _examplemsg2 = utils.randomString( utils.randRange( 4, 99 ), 3 ) + _examplemsg2 = rand.string( rand.number( 4, 99 ), 3 ) it "test stop method - Pull #5 stop", ( done )-> - _examplemsg = utils.randomString( utils.randRange( 4, 99 ), 3 ) + _examplemsg = rand.string( rand.number( 4, 99 ), 3 ) @timeout( 6000 ) idx = 0 diff --git a/_src/test/utils.coffee b/_src/test/utils.coffee deleted file mode 100644 index 5f4ccea..0000000 --- a/_src/test/utils.coffee +++ /dev/null @@ -1,53 +0,0 @@ -# # Utils -# -# ### Exports: *Object* -# -# A collection of helper functions - -# export the functions -module.exports = - ### - ## randomString - - `utils.randomString( string_length, speciallevel )` - - Generate a random string - - @param { Number } string_length string length to generate - @param { Number } speciallevel Level of complexity. - * 0 = only letters upper and lowercase, 52 possible chars; - * 1 = 0 + Numbers, 62 possible chars; - * 2 = 1 + "_-@:.", 67 possible chars; - * 3 = 2 + may speacial chars, 135 possible chars; - - @return { String } The gerated string - ### - randomString: ( string_length = 5, specialLevel = 0 ) -> - chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" - chars += "0123456789" if specialLevel >= 1 - chars += "_-@:." if specialLevel >= 2 - chars += "!\"§$%&/()=?*'_:;,.-#+¬”#£fi^\\˜·¯˙˚«∑€®†Ω¨⁄øπ•‘æœ@∆ºª©ƒ∂‚å–…∞µ~∫√ç≈¥" if specialLevel >= 3 - - randomstring = "" - i = 0 - - while i < string_length - rnum = Math.floor(Math.random() * chars.length) - randomstring += chars.substring(rnum, rnum + 1) - i++ - randomstring - - ### - ## randRange - - `utils.randRange( lowVal, highVal )` - - Create a random number bewtween two values - - @param { Number } lowVal Min number - @param { Number } highVal Max number - - @return { Number } A random number - ### - randRange: ( lowVal, highVal )-> - return Math.floor( Math.random()*(highVal-lowVal+1 ))+lowVal diff --git a/package.json b/package.json index 4b64b22..de37210 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rsmq-worker", - "version": "0.4.3", + "version": "0.5.0", "description": "RSMQ helper to simply implement a worker around the message queue", "keywords": [], "homepage": "https://github.com/mpneuried/rsmq-worker", @@ -23,19 +23,20 @@ }, "license": "MIT", "dependencies": { - "async": "1.5.x", + "async": "2.0.x", "lodash": "4.x", "mpbasic": "0.0.x", "rsmq": "0.7.x" }, "devDependencies": { - "should": "9.x", "grunt": "1.x", - "grunt-contrib-watch": "1.x", + "grunt-contrib-clean": "1.x", "grunt-contrib-coffee": "1.x", + "grunt-contrib-watch": "1.x", + "grunt-docker": "0.x", "grunt-include-replace": "4.x", "grunt-mocha-cli": "2.x", - "grunt-docker": "0.x", - "grunt-contrib-clean": "1.x" + "randoms": "0.x", + "should": "9.x" } }