netflix-conductor-utilities
Version:
Netflix conductor utilities
113 lines (95 loc) • 3.68 kB
text/typescript
import { RunningTaskCoreInfo, TaskState, UpdatingTaskResult } from './types';
import { base } from './utils/logger';
import ConductorWorker, { ConductorWorkerChainContext } from './ConductorWorker';
const debug = base.extend('RunningTask').extend('[DEBUG]');
const debugError = base.extend('RunningTask').extend('[Error]');
export interface KeepTaskTimerOptions {
keepAliveTimer: {
enable: boolean;
// ms
// need to " < responseTimeoutSeconds"
// Ref: https://netflix.github.io/conductor/configuration/taskdef/#task-definition
// default: 10000
interval: number;
// second
// need to " < responseTimeoutSeconds"
// Ref: https://netflix.github.io/conductor/configuration/taskdef/#task-definition
// default: 60
callbackAfterSeconds: number;
};
}
export type RunningTaskOptions = RunningTaskCoreInfo & KeepTaskTimerOptions;
export default class RunningTask<
OUTPUT = void,
INPUT = any,
CTX extends ConductorWorkerChainContext<any> = ConductorWorkerChainContext<OUTPUT, INPUT>,
> {
options: RunningTaskOptions;
worker: ConductorWorker<OUTPUT, INPUT, CTX>;
done: boolean;
start: number | undefined;
keepRunningTimer: NodeJS.Timeout | undefined;
constructor(
worker: ConductorWorker<OUTPUT, INPUT, CTX>,
options: RunningTaskCoreInfo & Partial<KeepTaskTimerOptions>,
) {
this.worker = worker;
// keepAliveTimer options
const { enable = false, interval = 10000, callbackAfterSeconds = 60 } = options?.keepAliveTimer || {};
this.options = { ...options, keepAliveTimer: { enable, interval, callbackAfterSeconds } };
this.done = false;
}
updateTaskInfo(partialUpdateTaskInfo: Partial<UpdatingTaskResult> & { status: TaskState }) {
const updateTaskInfo = { ...this.options, ...partialUpdateTaskInfo };
const { client, apiPath } = this.worker;
return client.post(`${apiPath}/tasks/`, updateTaskInfo);
}
private __setKeepTaskTimerForNotifyConductor() {
// clean old timer
this.__clearKeepTaskTimerForNotifyConductor();
// new a timer
// notify conductor: task is still running, and not put the queue back
debug(`start a keeping-task timer: ${this.options.keepAliveTimer.interval}`);
this.keepRunningTimer = setInterval(() => {
const callbackAfterSeconds = this.options.keepAliveTimer.callbackAfterSeconds;
debug(`notify keep-task: callbackAfterSeconds: ${callbackAfterSeconds}`);
this.updateTaskInfo({
status: TaskState.inProgress,
callbackAfterSeconds,
}).catch((error) => {
debugError(error);
});
}, this.options.keepAliveTimer.interval);
}
private __clearKeepTaskTimerForNotifyConductor() {
debug('clear a keeping-task timer');
if (this.keepRunningTimer) {
clearInterval(this.keepRunningTimer);
this.keepRunningTimer = undefined;
}
}
startTask() {
debug('start a task');
this.start = Date.now();
this.done = false;
this.options.keepAliveTimer.enable && this.__setKeepTaskTimerForNotifyConductor();
}
async sendLog(msg: string, others: Partial<UpdatingTaskResult> = {}) {
const otherInfo: Partial<UpdatingTaskResult> & { status: TaskState } = {
status: TaskState.inProgress,
...others,
};
if (this.options.keepAliveTimer.enable) {
otherInfo.callbackAfterSeconds = this.options.keepAliveTimer.callbackAfterSeconds;
}
return this.updateTaskInfo({
logs: [{ log: msg, createdTime: Date.now() }],
...otherInfo,
});
}
stopTask() {
debug('stop a task');
this.options.keepAliveTimer.enable && this.__clearKeepTaskTimerForNotifyConductor();
this.done = true;
}
}