UNPKG

@temporalio/worker

Version:
248 lines (247 loc) 9.53 kB
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;