UNPKG

@sap/cds

Version:

SAP Cloud Application Programming Model - CDS for Node.js

81 lines (71 loc) 2.29 kB
const PROCESSING = 'processing' const LOCKED = 'locked' const QUEUED = 'queued' const CALLBACKS = 'callbacks' module.exports = class JobExecutor { constructor() { statify(this) } run({ target, tenant, after }, cb) { const exec = () => { const processingState = this._get_state(PROCESSING, { target, tenant }) if (processingState === LOCKED) { this._set_state(PROCESSING, QUEUED, { target, tenant }) return } if (processingState === QUEUED) return if (!processingState) this._set_state(PROCESSING, LOCKED, { target, tenant }) return cb() } setTimeout(exec, after || 0).unref() } end({ target, tenant }, cb) { const processingState = this._get_state(PROCESSING, { target, tenant }) this._set_state(PROCESSING, undefined, { target, tenant }) if (processingState === QUEUED) { setTimeout(cb, 0).unref() } else { // Truly done - call all done callbacks const callbacks = this._clearCallbacks({ target, tenant }) if (callbacks) callbacks.forEach(callback => callback()) } } addCallback({ target, tenant }, callback) { const existing = this._get_state(CALLBACKS, { target, tenant }) || [] if (!existing.includes(callback)) { existing.push(callback) this._set_state(CALLBACKS, existing, { target, tenant }) } } _clearCallbacks({ target, tenant }) { const callbacks = this._get_state(CALLBACKS, { target, tenant }) this._set_state(CALLBACKS, undefined, { target, tenant }) return callbacks } } const statify = that => { if (that._states) return that._states = new Map() that._set_state = (prop, state, { target, tenant }) => { const statesSrv = that._states.get(target) if (!statesSrv) { const newStatesSrv = new Map() newStatesSrv.set(tenant, { [prop]: state }) that._states.set(target, newStatesSrv) return state } const obj = statesSrv.get(tenant) if (!obj) { statesSrv.set(tenant, { [prop]: state }) return state } obj[prop] = state return state } that._get_state = (prop, { target, tenant }) => { const statesSrv = that._states.get(target) if (!statesSrv) return const obj = statesSrv.get(tenant) return obj && obj[prop] } }