Skip to content

Instantly share code, notes, and snippets.

@KATT
Last active May 24, 2018 09:04
Show Gist options
  • Save KATT/aa8d35d1e02d772bc4d7cf95e6f30f0a to your computer and use it in GitHub Desktop.
Save KATT/aa8d35d1e02d772bc4d7cf95e6f30f0a to your computer and use it in GitHub Desktop.
/* eslint-disable no-underscore-dangle */
module.exports = ({
processEventEmitter,
logger,
skipRecurringOperationRefetch,
}) =>
class RecurringOperation {
constructor({ operation, expiry = null }) {
if (typeof operation !== 'function') {
throw new TypeError('Option `operation` has to be a function.');
}
if (expiry && typeof expiry !== 'function') {
throw new TypeError(
'Option `operation` has to be a function or falsy.',
);
}
this._operation = operation;
this._expiry = expiry;
this._listeningOnSigterm = false;
}
_listenOnSigterm() {
if (this._listeningOnSigterm) {
return;
}
this._listeningOnSigterm = true;
processEventEmitter.on('SIGTERM', () => {
clearTimeout(this._refreshTimer);
this._refreshTimer = null;
this._promise = null;
});
}
_scheduleNextRun(result) {
if (!this._expiry || skipRecurringOperationRefetch) {
return;
}
const expiry = this._expiry(result);
if (typeof expiry === 'number' && expiry > 0) {
this._refreshTimer = setTimeout(() => this.refresh(), expiry);
this._listenOnSigterm();
} else {
logger.warn(
`RecurringOperation: Unable to resolve valid expiry. Got "${
expiry
}" - expected number > 0`,
);
}
}
async refresh() {
try {
this._promise = this._operation();
const result = await this._promise;
this._scheduleNextRun(result);
} catch (err) {
this._promise = null;
logger.warn({ err }, `RecurringOperation: Failed executing operation.`);
}
}
async execute() {
if (!this._promise) {
this.refresh();
}
return this._promise;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment