UNPKG

@sap/cds

Version:

SAP Cloud Application Programming Model - CDS for Node.js

71 lines (64 loc) 2 kB
const PROCESSING = 'processing' const LOCKED = 'locked' const QUEUED = 'queued' const PLANNED = 'planned' module.exports = class TaskRunner { constructor() { this.states = new Map() } _setStateProp(prop, state, { name, tenant }) { const statesSrv = this.states.get(name) if (!statesSrv) { const newStatesSrv = new Map() newStatesSrv.set(tenant, { [prop]: state }) this.states.set(name, newStatesSrv) return state } const obj = statesSrv.get(tenant) if (!obj) { statesSrv.set(tenant, { [prop]: state }) return state } obj[prop] = state return state } _getStateProp(prop, { name, tenant }) { const statesSrv = this.states.get(name) if (!statesSrv) return const obj = statesSrv.get(tenant) return obj && obj[prop] } run({ name, tenant }, cb) { const processingState = this._getStateProp(PROCESSING, { name, tenant }) if (processingState === LOCKED) { this._setStateProp(PROCESSING, QUEUED, { name, tenant }) return } if (processingState === QUEUED) return if (!processingState) this._setStateProp(PROCESSING, LOCKED, { name, tenant }) return cb() } // Allows to plan, the shortest time wins plan({ name, tenant, waitingTime }, cb) { const newDate = Date.now() + waitingTime const alreadyPlanned = this._getStateProp(PLANNED, { name, tenant }) if (!alreadyPlanned || alreadyPlanned.date > newDate) { if (alreadyPlanned) clearInterval(alreadyPlanned.timer) this._setStateProp( PLANNED, { date: newDate, timer: setTimeout(() => (this._setStateProp(PLANNED, undefined, { name, tenant }), cb()), waitingTime) }, { name, tenant } ) } } end({ name, tenant }, cb) { const processingState = this._getStateProp(PROCESSING, { name, tenant }) this._setStateProp(PROCESSING, undefined, { name, tenant }) if (processingState === QUEUED) { return cb() } } }