Core synchronous queue with an example worker
This commit is contained in:
89
routes/calc-queue.js
Normal file
89
routes/calc-queue.js
Normal file
@@ -0,0 +1,89 @@
|
||||
const express = require('express')
|
||||
const statusCodes = require('http-status-codes').StatusCodes
|
||||
const calcQueueSvc = require('../src/services/calc-queue')
|
||||
const CalcQueueExceptions = require('../src/services/calc-queue/exceptions.js')
|
||||
|
||||
const router = express.Router()
|
||||
|
||||
// Return busy/not busy flag
|
||||
router.get('/busy', function(req, res) {
|
||||
res.send({ busy: calcQueueSvc.isBusy() })
|
||||
})
|
||||
|
||||
// Get the current queue of tasks
|
||||
router.get('/queue', function(req, res) {
|
||||
res.send({ 'queue': calcQueueSvc.getQueue() })
|
||||
})
|
||||
|
||||
// Add a calc task to the queue
|
||||
router.put('/queue/:id/:calcFn', function(req, res) {
|
||||
try {
|
||||
calcQueueSvc.enqueue(req.params.id, req.params.calcFn)
|
||||
res.send({ success: true })
|
||||
} catch(ex) {
|
||||
if (ex instanceof CalcQueueExceptions.AlreadyQueued
|
||||
|| ex instanceof CalcQueueExceptions.AlreadyInProgress
|
||||
|| ex instanceof CalcQueueExceptions.CalculationUnknown) {
|
||||
res.status(
|
||||
statusCodes.BAD_REQUEST
|
||||
).send(
|
||||
{ success: false, error: ex.message }
|
||||
)
|
||||
} else {
|
||||
throw ex
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Remove a task or collection of tasks from the queue
|
||||
router.delete('/queue/:id', function(req, res) {
|
||||
calcQueueSvc.dequeue(req.params.id, null)
|
||||
res.send({ success: true })
|
||||
})
|
||||
// Remove a task from the queue
|
||||
router.delete('/queue/:id/:calcFn', function(req, res) {
|
||||
calcQueueSvc.dequeue(req.params.id, req.params.calcFn)
|
||||
res.send({ success: true })
|
||||
})
|
||||
|
||||
|
||||
// Get the status of a task as a text string
|
||||
const processStatus = function(id, calcFn) {
|
||||
if (calcQueueSvc.isInProgress(id, calcFn)) {
|
||||
return 'in_progress'
|
||||
} else if (calcQueueSvc.isQueued(id, calcFn)) {
|
||||
return 'queued'
|
||||
} else if (calcQueueSvc.isFinished(id, calcFn)) {
|
||||
return 'finished'
|
||||
} else {
|
||||
return 'not_queued'
|
||||
}
|
||||
}
|
||||
|
||||
// Get the status of the queue and all tasks
|
||||
router.get('/status', function(req, res) {
|
||||
res.status(statusCodes.OK).send({
|
||||
'queued': calcQueueSvc.getQueue(),
|
||||
'in_progress': calcQueueSvc.getInProgress(),
|
||||
'finished': calcQueueSvc.getFinished()
|
||||
})
|
||||
})
|
||||
|
||||
// Get the status of all tasks with by id
|
||||
router.get('/status/:id', function(req, res) {
|
||||
res.status(statusCodes.OK).send({
|
||||
'id': req.params.id,
|
||||
'status': processStatus(req.params.id, null)
|
||||
})
|
||||
})
|
||||
|
||||
// Get the status of an individual task
|
||||
router.get('/status/:id/:calcFn', function(req, res) {
|
||||
res.status(statusCodes.OK).send({
|
||||
'id': req.params.id,
|
||||
'calcFn': req.params.calcFn,
|
||||
'status': processStatus(req.params.id, req.params.calcFn)
|
||||
})
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
37
routes/index.js
Normal file
37
routes/index.js
Normal file
@@ -0,0 +1,37 @@
|
||||
const dotenv = require('dotenv')
|
||||
const express = require('express')
|
||||
const statusCodes = require('http-status-codes').StatusCodes
|
||||
const createError = require('http-errors')
|
||||
|
||||
dotenv.config()
|
||||
|
||||
const router = express.Router()
|
||||
|
||||
// TODO: Add a mechanism for multiple clients/API keys
|
||||
const apiKeys = [
|
||||
process.env.API_KEY
|
||||
]
|
||||
|
||||
// Middleware to verify API access is granted
|
||||
router.use('/', function(req, res, next){
|
||||
var key = req.query['api_key'];
|
||||
|
||||
// key isn't present
|
||||
if (!key) {
|
||||
return next(createError(statusCodes.BAD_REQUEST, 'api key required'))
|
||||
}
|
||||
|
||||
// key is invalid
|
||||
if (!~apiKeys.indexOf(key)) {
|
||||
return next(createError(statusCodes.UNAUTHORIZED, 'invalid api key'))
|
||||
}
|
||||
|
||||
// all good, store req.key for route access
|
||||
req.key = key
|
||||
next()
|
||||
})
|
||||
|
||||
// Add API routes to default router
|
||||
router.use('/', require('./calc-queue.js'))
|
||||
|
||||
module.exports = router
|
||||
Reference in New Issue
Block a user