ready-callback
Version:
Launch server after all async task ready
112 lines • 8.37 kB
JavaScript
import EventEmitter from 'node:events';
import { debuglog } from 'node:util';
import { randomUUID } from 'node:crypto';
import once from 'once';
import { Ready as ReadyObject } from 'get-ready';
const debug = debuglog('ready-callback');
const defaults = {
timeout: 10000,
isWeakDep: false,
};
/**
* @class Ready
*/
class Ready extends EventEmitter {
isError = false;
cache = new Map();
opt;
obj;
ready;
constructor(opt = {}) {
super();
ReadyObject.mixin(this);
this.opt = opt;
if (!this.opt.lazyStart) {
this.start();
}
}
start() {
setImmediate(() => {
// fire callback directly when no registered ready callback
if (this.cache.size === 0) {
debug('Fire callback directly');
this.ready(true);
}
});
}
/**
* Mix `ready` and `readyCallback` to `obj`
* @function Ready#mixin
* @param {Object} obj - The mixed object
* @return {Ready} this
*/
mixin(obj) {
// only mixin once
if (!obj || this.obj)
return null;
// delegate API to object
obj.ready = this.ready.bind(this);
obj.readyCallback = this.readyCallback.bind(this);
// only ready once with error
this.once('error', err => obj.ready(err));
// delegate events
if (obj.emit) {
this.on('ready_timeout', obj.emit.bind(obj, 'ready_timeout'));
this.on('ready_stat', obj.emit.bind(obj, 'ready_stat'));
this.on('error', obj.emit.bind(obj, 'error'));
}
this.obj = obj;
return this;
}
readyCallback(name, opt = {}) {
opt = Object.assign({}, defaults, this.opt, opt);
const cacheKey = randomUUID();
opt.name = name || cacheKey;
const timer = setTimeout(() => this.emit('ready_timeout', opt.name), opt.timeout);
const cb = once((err) => {
if (err != null && !(err instanceof Error)) {
err = new Error(err);
}
clearTimeout(timer);
// won't continue to fire after it's error
if (this.isError === true)
return;
// fire callback after all register
setImmediate(() => this.readyDone(cacheKey, opt, err));
});
debug('[%s] Register task id `%s` with %j', cacheKey, opt.name, opt);
cb.id = opt.name;
this.cache.set(cacheKey, cb);
return cb;
}
readyDone(id, opt, err) {
if (err != null && !opt.isWeakDep) {
this.isError = true;
debug('[%s] Throw error task id `%s`, error %s', id, opt.name, err);
return this.emit('error', err);
}
debug('[%s] End task id `%s`, error %s', id, opt.name, err);
this.cache.delete(id);
this.emit('ready_stat', {
id: opt.name,
remain: getRemain(this.cache),
});
if (this.cache.size === 0) {
debug('[%s] Fire callback async', id);
this.ready(true);
}
return this;
}
}
function getRemain(map) {
const names = [];
for (const cb of map.values()) {
names.push(cb.id);
}
return names;
}
export { Ready };
export default function (opt = {}) {
return new Ready(opt);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxZQUFZLE1BQU0sYUFBYSxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDckMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN6QyxPQUFPLElBQUksTUFBTSxNQUFNLENBQUM7QUFDeEIsT0FBTyxFQUFFLEtBQUssSUFBSSxXQUFXLEVBQXlCLE1BQU0sV0FBVyxDQUFDO0FBRXhFLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0FBa0J6QyxNQUFNLFFBQVEsR0FBd0I7SUFDcEMsT0FBTyxFQUFFLEtBQUs7SUFDZCxTQUFTLEVBQUUsS0FBSztDQUNqQixDQUFDO0FBRUY7O0dBRUc7QUFDSCxNQUFNLEtBQU0sU0FBUSxZQUFZO0lBQzlCLE9BQU8sR0FBRyxLQUFLLENBQUM7SUFDaEIsS0FBSyxHQUF1QixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBRXRDLEdBQUcsQ0FBYztJQUNqQixHQUFHLENBQU07SUFFVCxLQUFLLENBQThDO0lBRW5ELFlBQVksTUFBbUIsRUFBRTtRQUMvQixLQUFLLEVBQUUsQ0FBQztRQUNSLFdBQVcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFeEIsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7UUFFZixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUU7WUFDdkIsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1NBQ2Q7SUFDSCxDQUFDO0lBRUQsS0FBSztRQUNILFlBQVksQ0FBQyxHQUFHLEVBQUU7WUFDaEIsMkRBQTJEO1lBQzNELElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssQ0FBQyxFQUFFO2dCQUN6QixLQUFLLENBQUMsd0JBQXdC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