runTimeHistory: new CircularArray(),
avgRunTime: 0,
medRunTime: 0,
+ waitTime: 0,
+ waitTimeHistory: new CircularArray(),
+ avgWaitTime: 0,
+ medWaitTime: 0,
error: 0
})
}
/** @inheritDoc */
public async execute (data?: Data, name?: string): Promise<Response> {
+ const submissionTimestamp = performance.now()
const workerNodeKey = this.chooseWorkerNode()
const submittedTask: Task<Data> = {
name,
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
data: data ?? ({} as Data),
+ submissionTimestamp,
id: crypto.randomUUID()
}
const res = new Promise<Response>((resolve, reject) => {
workerTasksUsage.medRunTime = median(workerTasksUsage.runTimeHistory)
}
}
+ if (this.workerChoiceStrategyContext.getRequiredStatistics().waitTime) {
+ workerTasksUsage.waitTime += message.waitTime ?? 0
+ if (
+ this.workerChoiceStrategyContext.getRequiredStatistics().avgWaitTime &&
+ workerTasksUsage.run !== 0
+ ) {
+ workerTasksUsage.avgWaitTime =
+ workerTasksUsage.waitTime / workerTasksUsage.run
+ }
+ if (
+ this.workerChoiceStrategyContext.getRequiredStatistics().medWaitTime &&
+ message.waitTime != null
+ ) {
+ workerTasksUsage.waitTimeHistory.push(message.waitTime)
+ workerTasksUsage.medWaitTime = median(workerTasksUsage.waitTimeHistory)
+ }
+ }
}
/**
runTimeHistory: new CircularArray(),
avgRunTime: 0,
medRunTime: 0,
+ waitTime: 0,
+ waitTimeHistory: new CircularArray(),
+ avgWaitTime: 0,
+ medWaitTime: 0,
error: 0
},
tasksQueue: new Queue<Task<Data>>()
public readonly requiredStatistics: RequiredStatistics = {
runTime: false,
avgRunTime: false,
- medRunTime: false
+ medRunTime: false,
+ waitTime: false,
+ avgWaitTime: false,
+ medWaitTime: false
}
/**
this.requiredStatistics.avgRunTime = true
this.requiredStatistics.medRunTime = opts.medRunTime as boolean
}
+ if (this.requiredStatistics.avgWaitTime && opts.medWaitTime === true) {
+ this.requiredStatistics.avgWaitTime = false
+ this.requiredStatistics.medWaitTime = opts.medWaitTime as boolean
+ }
+ if (this.requiredStatistics.medWaitTime && opts.medWaitTime === false) {
+ this.requiredStatistics.avgWaitTime = true
+ this.requiredStatistics.medWaitTime = opts.medWaitTime as boolean
+ }
}
/** @inheritDoc */
public readonly requiredStatistics: RequiredStatistics = {
runTime: true,
avgRunTime: true,
- medRunTime: false
+ medRunTime: false,
+ waitTime: false,
+ avgWaitTime: false,
+ medWaitTime: false
}
/**
public readonly requiredStatistics: RequiredStatistics = {
runTime: true,
avgRunTime: false,
- medRunTime: false
+ medRunTime: false,
+ waitTime: false,
+ avgWaitTime: false,
+ medWaitTime: false
}
/** @inheritDoc */
* @defaultValue false
*/
medRunTime?: boolean
+ /**
+ * Use tasks median wait time instead of average runtime.
+ *
+ * @defaultValue false
+ */
+ medWaitTime?: boolean
/**
* Worker weights to use for weighted round robin worker selection strategy.
* Weight is the tasks maximum average or median runtime in milliseconds.
* Require tasks median runtime.
*/
medRunTime: boolean
+ /**
+ * Require tasks wait time.
+ */
+ waitTime: boolean
+ /**
+ * Require tasks average wait time.
+ */
+ avgWaitTime: boolean
+ /**
+ * Require tasks median wait time.
+ */
+ medWaitTime: boolean
}
/**
public readonly requiredStatistics: RequiredStatistics = {
runTime: true,
avgRunTime: true,
- medRunTime: false
+ medRunTime: false,
+ waitTime: false,
+ avgWaitTime: false,
+ medWaitTime: false
}
/**
* Task input data that will be passed to the worker.
*/
readonly data?: Data
+ /**
+ * Submission timestamp.
+ */
+ readonly submissionTimestamp?: number
/**
* Message UUID.
*/
* Median tasks runtime.
*/
medRunTime: number
+ /**
+ * Tasks wait time.
+ */
+ waitTime: number
+ /**
+ * Tasks wait time history.
+ */
+ waitTimeHistory: CircularArray<number>
+ /**
+ * Average tasks wait time.
+ */
+ avgWaitTime: number
+ /**
+ * Median tasks wait time.
+ */
+ medWaitTime: number
/**
* Number of tasks errored.
*/
* Runtime.
*/
readonly runTime?: number
+ /**
+ * Wait time.
+ */
+ readonly waitTime?: number
/**
* Reference to main worker.
*/
): void {
try {
const startTimestamp = performance.now()
+ const waitTime = startTimestamp - (message.submissionTimestamp ?? 0)
const res = fn(message.data)
const runTime = performance.now() - startTimestamp
this.sendToMainWorker({
data: res,
id: message.id,
- runTime
+ runTime,
+ waitTime
})
} catch (e) {
const err = this.handleError(e as Error)
message: MessageValue<Data>
): void {
const startTimestamp = performance.now()
+ const waitTime = startTimestamp - (message.submissionTimestamp ?? 0)
fn(message.data)
.then(res => {
const runTime = performance.now() - startTimestamp
this.sendToMainWorker({
data: res,
id: message.id,
- runTime
+ runTime,
+ waitTime
})
return null
})