From 94465145e6d379d486ffd9a38429c085629ac96b Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Thu, 20 Apr 2017 17:35:27 -0500 Subject: [PATCH] Add support for epoch-scheduled jobs --- README.md | 1 + lib/gearmanode/client.js | 7 ++++++- lib/gearmanode/job.js | 11 +++++++++-- lib/gearmanode/protocol.js | 1 + test/test-job.js | 6 +++++- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6578570..5b28ede 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,7 @@ and `options` are additional options as follows: * **encoding** - {string} encoding if string data used, **DEPRECATED**: ignored, will be removed in next release, use Buffer with corresponding string encoding as payload * **unique** {string} unique identifiter for the job * **toStringEncoding** {string} if given received response will be converted to `String` with this encoding, otherwise payload turned over as `Buffer` +* **epochTime** {int} if given the job will not run before the given epoch time (will always be a background job!) ```javascript // by default foreground job with normal priority diff --git a/lib/gearmanode/client.js b/lib/gearmanode/client.js index 05942b4..e574765 100644 --- a/lib/gearmanode/client.js +++ b/lib/gearmanode/client.js @@ -145,7 +145,12 @@ Client.prototype.submitJob = function(name, payload, options) { if (job instanceof Error) { return job; } job.processing = true; - packet = protocol.encodePacket(job.getPacketType(), [job.name, (job.unique ? job.unique : ''), job.payload]); + var packetType = job.getPacketType(); + if (packetType === protocol.PACKET_TYPES.SUBMIT_JOB_EPOCH) { + packet = protocol.encodePacket(packetType, [job.name, (job.unique ? job.unique : ''), job.epochTime, job.payload]); + } else { + packet = protocol.encodePacket(packetType, [job.name, (job.unique ? job.unique : ''), job.payload]); + } var jsSendCallback = function(err) { if (err instanceof Error) { diff --git a/lib/gearmanode/job.js b/lib/gearmanode/job.js index 1f405b0..f4cc2a4 100644 --- a/lib/gearmanode/job.js +++ b/lib/gearmanode/job.js @@ -39,7 +39,7 @@ var Job = exports.Job = function (clientOrWorker, options) { // VALIDATION - common pattern = { - name: 'mandatory', payload: 'mandatory', unique: 'optional' + name: 'mandatory', payload: 'mandatory', unique: 'optional', epochTime: 'optional' }; returned = common.verifyOptions({ name: options.name, payload: options.payload }, pattern); if (returned instanceof Error) { return returned; } @@ -71,7 +71,12 @@ var Job = exports.Job = function (clientOrWorker, options) { this.toStringEncoding = options.toStringEncoding; } + if (options.epochTime && typeof options.epochTime !== 'number') { + return new Error('invalid epochTime: ' + options.epochTime); + options.background = true; + } this.background = options.background; + this.epochTime = options.epochTime; this.priority = options.priority; if (options.hasOwnProperty('unique')) { this.unique = options.unique; @@ -127,7 +132,9 @@ Job.prototype.close = function () { * Gets packet type for submiting a job. according to job's options. */ Job.prototype.getPacketType = function () { - if (this.background) { + if (this.epochTime) { + return protocol.PACKET_TYPES.SUBMIT_JOB_EPOCH; + } else if (this.background) { if (this.priority == 'LOW') { return protocol.PACKET_TYPES.SUBMIT_JOB_LOW_BG; } if (this.priority == 'NORMAL') { return protocol.PACKET_TYPES.SUBMIT_JOB_BG; } if (this.priority == 'HIGH') { return protocol.PACKET_TYPES.SUBMIT_JOB_HIGH_BG; } diff --git a/lib/gearmanode/protocol.js b/lib/gearmanode/protocol.js index b90b6ef..338c967 100644 --- a/lib/gearmanode/protocol.js +++ b/lib/gearmanode/protocol.js @@ -62,6 +62,7 @@ exports.DEFINITION = { SUBMIT_JOB_HIGH_BG: [32, constants.TYPE_REQ], // C->J: FUNC[0]UNIQ[0]ARGS SUBMIT_JOB_LOW: [33, constants.TYPE_REQ], // C->J: FUNC[0]UNIQ[0]ARGS SUBMIT_JOB_LOW_BG: [34, constants.TYPE_REQ], // C->J: FUNC[0]UNIQ[0]ARGS + SUBMIT_JOB_EPOCH: [36, constants.TYPE_REQ], // C->J: FUNC[0]UNIQ[0]ARGS }; diff --git a/test/test-job.js b/test/test-job.js index 6e61db7..927e26c 100644 --- a/test/test-job.js +++ b/test/test-job.js @@ -23,6 +23,7 @@ describe('Job', function() { j.background.should.be.false; j.priority.should.equal('NORMAL'); j.encoding.should.equal('utf8'); + should.not.exist(j.epochTime); should.not.exist(j.unique); should.exist(j.uuid); should.not.exist(j.jobServer); @@ -30,7 +31,7 @@ describe('Job', function() { }) it('should store additional options', function() { var job = new Job(c, - { name: 'reverse', payload: 'hi', background: true, priority: 'HIGH', toStringEncoding: 'ascii', encoding: 'ascii', unique: 'foo' } + { name: 'reverse', payload: 'hi', background: true, priority: 'HIGH', toStringEncoding: 'ascii', encoding: 'ascii', unique: 'foo', epochTime: 1234 } ); job.should.be.an.instanceof(Job); job.name.should.equal('reverse'); @@ -40,6 +41,7 @@ describe('Job', function() { job.encoding.should.equal('ascii'); job.toStringEncoding.should.equal('ascii'); job.unique.should.equal('foo'); + job.epochTime.should.equal(1234); }) it('should return error when missing mandatory options', function() { var job = new Job(); @@ -66,6 +68,8 @@ describe('Job', function() { job.should.be.an.instanceof(Error); job = new Job(c, { name: 'foo', payload: 'bar', toStringEncoding: 'baz' }); job.should.be.an.instanceof(Error); + job = new Job(c, { name: 'foo', payload: 'bar', epochTime: '1234' }); + job.should.be.an.instanceof(Error); }) })