-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
let the worker process handle the expensive bulk upsert call
- Loading branch information
1 parent
1239a21
commit 372f5e4
Showing
13 changed files
with
356 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
web: npm start | ||
clock: npm run start-clock | ||
worker: npm run start-worker |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/** | ||
* Copyright (c) 2016, salesforce.com, inc. | ||
* All rights reserved. | ||
* Licensed under the BSD 3-Clause license. | ||
* For full license text, see LICENSE.txt file in the repo root or | ||
* https://opensource.org/licenses/BSD-3-Clause | ||
*/ | ||
|
||
/** | ||
* /jobQueue/jobWrapper.js | ||
* | ||
* Expsoses a wrapper to create jobs and save them to the redis queue for | ||
* it to be processed by the workers later. The "kue" library defined in the | ||
* setup is used for this purpose. | ||
*/ | ||
|
||
'use strict'; // eslint-disable-line strict | ||
|
||
const jobQueue = require('./setup').jobQueue; | ||
|
||
const delayToRemoveJobs = 3000; | ||
|
||
/** | ||
* Listen for a job completion event and clean up (remove) the job. The delay | ||
* is introduced to avoid the job.id leakage. | ||
* TODO: This needs to be moved to the clock process, once we start exposing | ||
* APIs to monitor the jobs. | ||
* @param {Object} job - Job object to be cleaned up from the queue | ||
* | ||
*/ | ||
function cleanUpJobOnComplete(job) { | ||
if (job) { | ||
job.on('complete', () => { | ||
setTimeout(() => { | ||
job.remove(); | ||
}, delayToRemoveJobs); | ||
}); | ||
} | ||
} | ||
|
||
/** | ||
* Creates a job to be prossed using the KUE api, when given the jobName and | ||
* data to be processed by the job | ||
* @param {String} jobName - Name of the job (A worker process should be | ||
* listning to this jobName for it to be processed) | ||
* @param {Json} data - Data for the job to work with. | ||
* @returns {Object} - A job object | ||
*/ | ||
function createJob(jobName, data) { | ||
// jobQueue.create will return undefined when it is created in the test mode | ||
const job = jobQueue.create(jobName, data) | ||
.save((err) => { | ||
if (err) { | ||
throw new Error('There was a problem in adding the job: ' + jobName + | ||
', with id:' + job.id + 'to the worker queue'); | ||
} | ||
}); | ||
cleanUpJobOnComplete(job); | ||
return job; | ||
} | ||
module.exports = { | ||
jobQueue, | ||
createJob | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/** | ||
* Copyright (c) 2016, salesforce.com, inc. | ||
* All rights reserved. | ||
* Licensed under the BSD 3-Clause license. | ||
* For full license text, see LICENSE.txt file in the repo root or | ||
* https://opensource.org/licenses/BSD-3-Clause | ||
*/ | ||
|
||
/** | ||
* /jobQueue/setup.js | ||
* | ||
* Setup the "Kue" library to process background jobs | ||
*/ | ||
|
||
'use strict'; // eslint-disable-line strict | ||
|
||
const conf = require('../config'); | ||
const env = conf.environment[conf.nodeEnv]; | ||
const urlParser = require('url'); | ||
const kue = require('kue'); | ||
|
||
let redisUrl = env.redisUrl; | ||
const redisOptions = {}; | ||
if (redisUrl) { | ||
const redisInfo = urlParser.parse(redisUrl, true); | ||
|
||
if (redisInfo.protocol !== 'redis:') { | ||
redisUrl = 'redis:' + redisUrl; | ||
} | ||
|
||
redisOptions.redis = redisUrl; | ||
} | ||
|
||
// create a job queue using the redis options specified | ||
const jobQueue = kue.createQueue(redisOptions); | ||
|
||
module.exports = { | ||
jobQueue, | ||
jobType: { | ||
BULKUPSERTSAMPLES: 'bulkUpsertSamples', | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
/** | ||
* Copyright (c) 2016, salesforce.com, inc. | ||
* All rights reserved. | ||
* Licensed under the BSD 3-Clause license. | ||
* For full license text, see LICENSE.txt file in the repo root or | ||
* https://opensource.org/licenses/BSD-3-Clause | ||
*/ | ||
|
||
/** | ||
* tests/jobQueue/v1/bulkUpsert.js | ||
*/ | ||
'use strict'; | ||
|
||
const jobQueue = require('../../../jobQueue/setup').jobQueue; | ||
const jobType = require('../../../jobQueue/setup').jobType; | ||
const expect = require('chai').expect; | ||
const supertest = require('supertest'); | ||
const api = supertest(require('../../../index').app); | ||
const tu = require('../../testUtils'); | ||
const u = require('./utils'); | ||
const constants = require('../../../api/v1/constants'); | ||
const Aspect = tu.db.Aspect; | ||
const Subject = tu.db.Subject; | ||
const path = '/v1/samples/upsert/bulk'; | ||
describe('api: POST ' + path, () => { | ||
let token; | ||
|
||
before((done) => { | ||
tu.createToken() | ||
.then((returnedToken) => { | ||
token = returnedToken; | ||
done(); | ||
}) | ||
.catch((err) => done(err)); | ||
}); | ||
// force the job queue to enter the test mode. | ||
beforeEach((done) => { | ||
jobQueue.testMode.enter(); | ||
done(); | ||
}); | ||
|
||
before((done) => { | ||
Aspect.create({ | ||
isPublished: true, | ||
name: `${tu.namePrefix}Aspect1`, | ||
timeout: '30s', | ||
valueType: 'NUMERIC', | ||
criticalRange: [0, 1], | ||
}) | ||
.then(() => Aspect.create({ | ||
isPublished: true, | ||
name: `${tu.namePrefix}Aspect2`, | ||
timeout: '10m', | ||
valueType: 'BOOLEAN', | ||
okRange: [10, 100], | ||
})) | ||
.then(() => Subject.create({ | ||
isPublished: true, | ||
name: `${tu.namePrefix}Subject`, | ||
})) | ||
.then(() => done()) | ||
.catch((err) => done(err)); | ||
}); | ||
|
||
|
||
afterEach(() => { | ||
jobQueue.testMode.clear(); | ||
}); | ||
|
||
after(u.forceDelete); | ||
after(tu.forceDeleteUser); | ||
|
||
it('sample bulkUpsert should be sent to the queue', (done) => { | ||
api.post(path) | ||
.set('Authorization', token) | ||
.send([ | ||
{ | ||
name: `${tu.namePrefix}Subject|${tu.namePrefix}Aspect1`, | ||
value: '2', | ||
}, { | ||
name: `${tu.namePrefix}Subject|${tu.namePrefix}Aspect2`, | ||
value: '4', | ||
}, | ||
]) | ||
.expect(constants.httpStatus.OK) | ||
.end((err) => { | ||
if (err) { | ||
return done(err); | ||
} | ||
// make sure only 1 job is created for each bulk upsert call | ||
expect(jobQueue.testMode.jobs.length).to.equal(1); | ||
// make sure the job type is correct | ||
expect(jobQueue.testMode.jobs[0].type) | ||
.to.equal(jobType.BULKUPSERTSAMPLES); | ||
// make sure the queue has the right data inside it | ||
expect(jobQueue.testMode.jobs[0].data).to.have.length(2); | ||
expect(jobQueue.testMode.jobs[0].data[0]) | ||
.to.have.all.keys('name', 'value'); | ||
|
||
return done(); | ||
}); | ||
}); | ||
|
||
it('should still return ok for good or bad samples', (done) => { | ||
api.post(path) | ||
.set('Authorization', token) | ||
.send([ | ||
{ | ||
name: `${tu.namePrefix}NOT_EXIST|${tu.namePrefix}Aspect1`, | ||
value: '2', | ||
}, { | ||
name: `${tu.namePrefix}Subject|${tu.namePrefix}Aspect2`, | ||
value: '4', | ||
}, | ||
]) | ||
.expect(constants.httpStatus.OK) | ||
.expect((res) => { | ||
expect(res.body.status).to.contain('OK'); | ||
}) | ||
.end((err, res) => { | ||
if (err) { | ||
return done(err); | ||
} | ||
|
||
return done(); | ||
}); | ||
}); | ||
}); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/** | ||
* Copyright (c) 2016, salesforce.com, inc. | ||
* All rights reserved. | ||
* Licensed under the BSD 3-Clause license. | ||
* For full license text, see LICENSE.txt file in the repo root or | ||
* https://opensource.org/licenses/BSD-3-Clause | ||
*/ | ||
|
||
/** | ||
* tests/jobQueue/v1/jobWrapper.js | ||
*/ | ||
'use strict'; | ||
|
||
const jobQueue = require('../../../jobQueue/jobWrapper').jobQueue; | ||
const expect = require('chai').expect; | ||
const tu = require('../../testUtils'); | ||
const u = require('./utils'); | ||
const path = '/v1/samples/upsert/bulk'; | ||
|
||
describe('api: POST ' + path, () => { | ||
after(u.forceDelete); | ||
after(tu.forceDeleteUser); | ||
|
||
it('jobWrapper should let you create any job type of job', (done) => { | ||
const jobType = 'myTestJob'; | ||
const testData = { foo: 'bar' }; | ||
const job = jobQueue.createJob(jobType, testData); | ||
expect(job).to.not.equal(null); | ||
expect(job.type).to.equal(jobType); | ||
expect(job.data).to.equal(testData); | ||
done(); | ||
}); | ||
}); | ||
|
Oops, something went wrong.