UNPKG

@fedify/fedify

Version:

An ActivityPub server framework

208 lines 7.68 kB
/// <reference lib="esnext.temporal" /> //#region src/federation/mq.d.ts /** * Additional options for enqueuing a message in a queue. * * @since 0.5.0 */ interface MessageQueueEnqueueOptions { /** * The delay before the message is enqueued. No delay by default. * * It must not be negative. */ readonly delay?: Temporal.Duration; /** * An optional key that ensures messages with the same ordering key are * processed sequentially (one at a time). Messages with different ordering * keys (or no ordering key) may be processed in parallel. * * This is useful for ensuring that related messages are processed in order, * such as ensuring that a `Delete` activity is processed after a `Create` * activity for the same object. * * @since 2.0.0 */ readonly orderingKey?: string; } /** * Additional options for listening to a message queue. * * @since 1.0.0 */ interface MessageQueueListenOptions { /** * The signal to abort listening to the message queue. */ signal?: AbortSignal; } /** * The number of messages waiting in a message queue. * * @since 2.3.0 */ interface MessageQueueDepth { /** * The total number of messages still waiting in the backend queue. * * This does not include messages that have already been handed to a worker * for processing. */ readonly queued: number; /** * The number of queued messages eligible for immediate processing. * * Queue backends that cannot cheaply distinguish ready and delayed messages * may omit this field. */ readonly ready?: number; /** * The number of queued messages scheduled for later delivery. * * Queue backends that cannot cheaply distinguish ready and delayed messages * may omit this field. */ readonly delayed?: number; } /** * An abstract interface for a message queue. * * @since 0.5.0 */ interface MessageQueue { /** * Whether the message queue backend provides native retry mechanisms. * When `true`, Fedify will skip its own retry logic and rely on the backend * to handle retries. When `false` or omitted, Fedify will handle retries * using its own retry policies. * * @default `false` * @since 1.7.0 */ readonly nativeRetrial?: boolean; /** * Enqueues a message in the queue. * @param message The message to enqueue. * @param options Additional options for enqueuing the message. */ enqueue(message: any, options?: MessageQueueEnqueueOptions): Promise<void>; /** * Enqueues multiple messages in the queue. This operation is optional, * and may not be supported by all implementations. If not supported, * Fedify will invoke {@link enqueue} for each message. * * @param messages The messages to enqueue. * @param options Additional options for enqueuing the messages. */ enqueueMany?: (messages: readonly any[], options?: MessageQueueEnqueueOptions) => Promise<void>; /** * Listens for messages in the queue. * @param handler The handler for messages in the queue. * @param options Additional options for listening to the message queue. * @returns A promise that resolves when the listening is done. It never * rejects, and is resolved when the signal is aborted. If no * signal is provided, it never resolves. */ listen(handler: (message: any) => Promise<void> | void, options?: MessageQueueListenOptions): Promise<void>; /** * Gets the number of messages waiting in the queue. * * This operation is optional, and may not be supported by all * implementations. The returned counts exclude messages currently being * handled by a worker. * * @since 2.3.0 */ getDepth?(): Promise<MessageQueueDepth>; } /** * Additional options for {@link InProcessMessageQueue}. * @since 1.0.0 */ interface InProcessMessageQueueOptions { /** * The interval to poll for messages in the queue. 5 seconds by default. * @default `{ seconds: 5 }` */ pollInterval?: Temporal.Duration | Temporal.DurationLike; } /** * A message queue that processes messages in the same process. * Do not use this in production as it does neither persist messages nor * distribute them across multiple processes. * * @since 0.5.0 */ declare class InProcessMessageQueue implements MessageQueue { #private; /** * In-process message queue does not provide native retry mechanisms. * @since 1.7.0 */ readonly nativeRetrial = false; /** * Constructs a new {@link InProcessMessageQueue} with the given options. * @param options Additional options for the in-process message queue. */ constructor(options?: InProcessMessageQueueOptions); enqueue(message: any, options?: MessageQueueEnqueueOptions): Promise<void>; enqueueMany(messages: readonly any[], options?: MessageQueueEnqueueOptions): Promise<void>; listen(handler: (message: any) => Promise<void> | void, options?: MessageQueueListenOptions): Promise<void>; getDepth(): Promise<MessageQueueDepth>; } /** * A message queue that processes messages in parallel. It takes another * {@link MessageQueue}, and processes messages in parallel up to a certain * number of workers. * * Actually, it's rather a decorator than a queue itself. * * Note that the workers do not run in truly parallel, in the sense that they * are not running in separate threads or processes. They are running in the * same process, but are scheduled to run in parallel. Hence, this is useful * for I/O-bound tasks, but not for CPU-bound tasks, which is okay for Fedify's * workloads. * * When using `ParallelMessageQueue`, the ordering guarantee is preserved * *only if* the underlying queue implementation delivers messages in a wrapper * format that includes the `__fedify_ordering_key__` property. Currently, * only `DenoKvMessageQueue` and `WorkersMessageQueue` use this format. * For other queue implementations (e.g., `InProcessMessageQueue`, * `RedisMessageQueue`, `PostgresMessageQueue`, `SqliteMessageQueue`, * `AmqpMessageQueue`), the ordering key cannot be detected by * `ParallelMessageQueue`, so ordering guarantees are handled by those * implementations directly rather than at the `ParallelMessageQueue` level. * * Messages with the same ordering key will never be processed concurrently * by different workers, ensuring sequential processing within each key. * Messages with different ordering keys (or no ordering key) can still be * processed in parallel. * * @since 1.0.0 */ declare class ParallelMessageQueue implements MessageQueue { #private; readonly queue: MessageQueue; readonly workers: number; /** * Inherits the native retry capability from the wrapped queue. * @since 1.7.0 */ readonly nativeRetrial?: boolean; readonly getDepth?: () => Promise<MessageQueueDepth>; /** * Constructs a new {@link ParallelMessageQueue} with the given queue and * number of workers. * @param queue The message queue to use under the hood. Note that * {@link ParallelMessageQueue} cannot be nested. * @param workers The number of workers to process messages in parallel. * @throws {TypeError} If the given queue is an instance of * {@link ParallelMessageQueue}. */ constructor(queue: MessageQueue, workers: number); enqueue(message: any, options?: MessageQueueEnqueueOptions): Promise<void>; enqueueMany(messages: readonly any[], options?: MessageQueueEnqueueOptions): Promise<void>; listen(handler: (message: any) => Promise<void> | void, options?: MessageQueueListenOptions): Promise<void>; } //#endregion export { MessageQueueEnqueueOptions as a, MessageQueueDepth as i, InProcessMessageQueueOptions as n, MessageQueueListenOptions as o, MessageQueue as r, ParallelMessageQueue as s, InProcessMessageQueue as t };