@temporalio/worker
Version:
Temporal.io SDK Worker sub-package
248 lines (247 loc) • 9.53 kB
TypeScript
import { native } from '@temporalio/core-bridge';
import { Duration } from '@temporalio/common/lib/time';
import { Logger, WorkerDeploymentVersion } from '@temporalio/common';
/**
* A worker tuner allows the customization of the performance characteristics of workers by
* controlling how "slots" are handed out for different task types. In order to poll for and then
* run tasks, a slot must first be reserved by the {@link SlotSupplier} returned by the tuner.
*
* @experimental Worker Tuner is an experimental feature and may be subject to change.
*/
export type WorkerTuner = ResourceBasedTuner | TunerHolder;
/**
* This tuner allows for different slot suppliers for different slot types.
*
* @experimental Worker Tuner is an experimental feature and may be subject to change.
*/
export interface TunerHolder {
workflowTaskSlotSupplier: SlotSupplier<WorkflowSlotInfo>;
activityTaskSlotSupplier: SlotSupplier<ActivitySlotInfo>;
localActivityTaskSlotSupplier: SlotSupplier<LocalActivitySlotInfo>;
}
/**
* Controls how slots are handed out for a specific task type.
*
* @experimental Worker Tuner is an experimental feature and may be subject to change.
*/
export type SlotSupplier<SI extends SlotInfo> = ResourceBasedSlotsForType | FixedSizeSlotSupplier | CustomSlotSupplier<SI>;
/**
* This tuner attempts to maintain certain levels of resource usage when under load. You do not
* need more than one instance of this when using it for multiple slot types.
*
* @experimental Worker Tuner is an experimental feature and may be subject to change.
*/
export interface ResourceBasedTuner {
/**
* Options for the tuner
*/
tunerOptions: ResourceBasedTunerOptions;
/**
* Options for workflow task slots. Defaults to a minimum of 2 slots and a maximum of 1000 slots
* with no ramp throttle
*/
workflowTaskSlotOptions?: ResourceBasedSlotOptions;
/**
* Options for activity task slots. Defaults to a minimum of 1 slots and a maximum of 2000 slots
* with 50ms ramp throttle
*/
activityTaskSlotOptions?: ResourceBasedSlotOptions;
/**
* Options for local activity task slots. Defaults to a minimum of 1 slots and a maximum of 2000
* slots with 50ms ramp throttle
*/
localActivityTaskSlotOptions?: ResourceBasedSlotOptions;
}
/**
* Options for a {@link ResourceBasedTuner} to control target resource usage
*
* @experimental Worker Tuner is an experimental feature and may be subject to change.
*/
export interface ResourceBasedTunerOptions {
targetMemoryUsage: number;
targetCpuUsage: number;
}
/**
* Options for a specific slot type within a {@link ResourceBasedSlotsForType}
*
* @experimental Worker Tuner is an experimental feature and may be subject to change.
*/
export interface ResourceBasedSlotOptions {
/**
* Amount of slots that will be issued regardless of any other checks.
* Defaults to 2 for workflow tasks and 1 for activity tasks.
*/
minimumSlots?: number;
/**
* Maximum amount of slots permitted
* Defaults to 1000 for workflow tasks and 2000 for activity tasks.
*/
maximumSlots?: number;
/**
* Minimum time we will wait (after passing the minimum slots number) between handing out new
* slots. Defaults to 10ms for workflow tasks and 50ms for activity tasks.
*/
rampThrottle?: Duration;
}
/**
* Resource based slot supplier options for a specific kind of slot.
*
* @experimental Worker Tuner is an experimental feature and may be subject to change.
*/
export type ResourceBasedSlotsForType = ResourceBasedSlotOptions & {
type: 'resource-based';
tunerOptions: ResourceBasedTunerOptions;
};
/**
* A fixed-size slot supplier that will never issue more than a fixed number of slots.
*
* @experimental Worker Tuner is an experimental feature and may be subject to change.
*/
export interface FixedSizeSlotSupplier {
type: 'fixed-size';
numSlots: number;
}
/**
* The interface can be implemented to provide custom slot supplier behavior.
*
* @experimental Worker Tuner is an experimental feature and may be subject to change.
*/
export interface CustomSlotSupplier<SI extends SlotInfo> {
type: 'custom';
/**
* This function is called before polling for new tasks. Your implementation should return a permit
* when a slot is available.
*
* Note: This function is called asynchronously from the Rust side. It should return a Promise that
* resolves when a slot is available. You can use async/await or return a Promise directly.
*
* The only acceptable exception to throw is AbortError, any other exceptions thrown will be
* logged and ignored.
*
* The value inside the returned promise should be an object, however other types will still count
* as having issued a permit. Including undefined or null. Returning undefined or null does *not*
* mean you have not issued a permit. Implementations are expected to block until a meaningful
* permit can be issued.
*
* @param ctx The context for slot reservation.
* @param abortSignal The SDK may decide to abort the reservation request if it's no longer
* needed. Implementations may clean up and then must reject the promise with AbortError.
* @returns A promise that resolves to a permit to use the slot which may be populated with your own data.
*/
reserveSlot(ctx: SlotReserveContext, abortSignal: AbortSignal): Promise<SlotPermit>;
/**
* This function is called when trying to reserve slots for "eager" workflow and activity tasks.
* Eager tasks are those which are returned as a result of completing a workflow task, rather than
* from polling. Your implementation must not block, and if a slot is available, return a permit
* to use that slot.
*
* @param ctx The context for slot reservation.
* @returns Maybe a permit to use the slot which may be populated with your own data.
*/
tryReserveSlot(ctx: SlotReserveContext): SlotPermit | null;
/**
* This function is called once a slot is actually being used to process some task, which may be
* some time after the slot was reserved originally. For example, if there is no work for a
* worker, a number of slots equal to the number of active pollers may already be reserved, but
* none of them are being used yet. This call should be non-blocking.
*
* @param ctx The context for marking a slot as used.
*/
markSlotUsed(ctx: SlotMarkUsedContext<SI>): void;
/**
* This function is called once a permit is no longer needed. This could be because the task has
* finished, whether successfully or not, or because the slot was no longer needed (ex: the number
* of active pollers decreased). This call should be non-blocking.
*
* @param ctx The context for releasing a slot.
*/
releaseSlot(ctx: SlotReleaseContext<SI>): void;
}
export type SlotInfo = WorkflowSlotInfo | ActivitySlotInfo | LocalActivitySlotInfo;
export interface WorkflowSlotInfo {
type: 'workflow';
workflowType: string;
isSticky: boolean;
}
export interface ActivitySlotInfo {
type: 'activity';
activityType: string;
}
export interface LocalActivitySlotInfo {
type: 'local-activity';
activityType: string;
}
/**
* A permit to use a slot.
*
* @experimental Worker Tuner is an experimental feature and may be subject to change.
*/
export interface SlotPermit {
}
/**
* Context for reserving a slot.
*
* @experimental Worker Tuner is an experimental feature and may be subject to change.
*/
export interface SlotReserveContext {
/**
* The type of slot trying to be reserved
*/
slotType: SlotInfo['type'];
/**
* The name of the task queue for which this reservation request is associated
*/
taskQueue: string;
/**
* The identity of the worker that is requesting the reservation
*/
workerIdentity: string;
/**
* The build id of the worker that is requesting the reservation
*
* @deprecated Use {@link workerDeploymentVersion} instead.
*/
workerBuildId: string;
/**
* The deployment version of the worker that is requesting the reservation
*
* @experimental Worker deployments are an experimental feature and may be subject to change.
*/
workerDeploymentVersion?: WorkerDeploymentVersion;
/**
* True iff this is a reservation for a sticky poll for a workflow task
*/
isSticky: boolean;
}
/**
* Context for marking a slot as used.
*
* @experimental Worker Tuner is an experimental feature and may be subject to change.
*/
export interface SlotMarkUsedContext<SI extends SlotInfo> {
/**
* Info about the task that will be using the slot
*/
slotInfo: SI;
/**
* The permit that was issued when the slot was reserved
*/
permit: SlotPermit;
}
/**
* Context for releasing a slot.
*
* @experimental Worker Tuner is an experimental feature and may be subject to change.
*/
export interface SlotReleaseContext<SI extends SlotInfo> {
/**
* Info about the task that used this slot, if any. A slot may be released without being used in
* the event a poll times out.
*/
slotInfo?: SI;
/**
* The permit that was issued when the slot was reserved
*/
permit: SlotPermit;
}
export declare function asNativeTuner(tuner: WorkerTuner, logger: Logger): native.WorkerTunerOptions;