@trigger.dev/redis-worker 4.5.11 → 4.5.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -717,6 +717,8 @@ interface FairQueueOptions<TPayloadSchema extends z.ZodTypeAny = z.ZodUnknown> {
717
717
  heartbeatIntervalMs?: number;
718
718
  /** Interval for reclaiming timed-out messages (default: 5000) */
719
719
  reclaimIntervalMs?: number;
720
+ /** Interval for sweeping orphaned concurrency slots; 0 disables the sweep (default: 60000) */
721
+ reconcileIntervalMs?: number;
720
722
  /** Number of consumer loops to run (default: 1) */
721
723
  consumerCount?: number;
722
724
  /** Interval between consumer iterations in milliseconds (default: 100) */
@@ -915,6 +917,10 @@ interface ConcurrencyManagerOptions {
915
917
  redis: RedisOptions;
916
918
  keys: FairQueueKeyProducer;
917
919
  groups: ConcurrencyGroupConfig[];
920
+ logger?: {
921
+ debug: (message: string, context?: Record<string, unknown>) => void;
922
+ error: (message: string, context?: Record<string, unknown>) => void;
923
+ };
918
924
  }
919
925
  /**
920
926
  * ConcurrencyManager handles multi-level concurrency tracking and limiting.
@@ -931,6 +937,7 @@ declare class ConcurrencyManager {
931
937
  private keys;
932
938
  private groups;
933
939
  private groupsByName;
940
+ private logger;
934
941
  constructor(options: ConcurrencyManagerOptions);
935
942
  /**
936
943
  * Check if a message can be processed given all concurrency constraints.
@@ -956,6 +963,24 @@ declare class ConcurrencyManager {
956
963
  queue: QueueDescriptor;
957
964
  messageId: string;
958
965
  }>): Promise<void>;
966
+ /**
967
+ * Remove concurrency set members that no longer correspond to an in-flight message,
968
+ * healing slots leaked by failed releases. Scans every set of every group and, per
969
+ * member, atomically removes it unless the message id appears in one of the given
970
+ * in-flight data hashes. Sound because a message is registered in-flight before its
971
+ * slot is reserved, so at the moment of the atomic check a member with no in-flight
972
+ * record can only be a leak; if the message is about to be re-claimed, reserve simply
973
+ * re-adds the member.
974
+ *
975
+ * @param inflightDataKeys - The in-flight data hash keys for every shard. The sweep
976
+ * refuses to run when this is empty, since with nowhere to look for running messages
977
+ * every member would look orphaned and all concurrency accounting would be erased.
978
+ * @returns The message ids that were removed, and how many sets were checked
979
+ */
980
+ sweepOrphanedSlots(inflightDataKeys: string[]): Promise<{
981
+ scannedSets: number;
982
+ removed: string[];
983
+ }>;
959
984
  /**
960
985
  * Get current concurrency for a specific group.
961
986
  */
@@ -1003,6 +1028,7 @@ declare class ConcurrencyManager {
1003
1028
  declare module "@internal/redis" {
1004
1029
  interface RedisCommander<Context> {
1005
1030
  reserveConcurrency(numKeys: number, keys: string[], messageId: string, ...limits: string[]): Promise<number>;
1031
+ removeOrphanedConcurrencySlots(numKeys: number, keys: string[], ...messageIds: string[]): Promise<string[]>;
1006
1032
  }
1007
1033
  }
1008
1034
  //#endregion
@@ -1811,7 +1837,10 @@ declare class VisibilityManager {
1811
1837
  *
1812
1838
  * @param shardId - The shard to check
1813
1839
  * @param getQueueKeys - Function to get queue keys for a queue ID
1814
- * @returns Array of reclaimed message info for concurrency release
1840
+ * @param onBeforeRequeue - Hook invoked with the batch before any message is requeued,
1841
+ * used to free concurrency slots. A throw aborts the whole batch, leaving the
1842
+ * messages in-flight for the next reclaim tick.
1843
+ * @returns Array of reclaimed message info
1815
1844
  */
1816
1845
  reclaimTimedOut(shardId: number, getQueueKeys: (queueId: string) => {
1817
1846
  queueKey: string;
@@ -1819,7 +1848,7 @@ declare class VisibilityManager {
1819
1848
  tenantQueueIndexKey: string;
1820
1849
  dispatchKey: string;
1821
1850
  tenantId: string;
1822
- }): Promise<ReclaimedMessageInfo[]>;
1851
+ }, onBeforeRequeue?: (messages: ReclaimedMessageInfo[]) => Promise<void>): Promise<ReclaimedMessageInfo[]>;
1823
1852
  /**
1824
1853
  * Get all in-flight messages for a shard.
1825
1854
  */
@@ -1994,6 +2023,7 @@ declare class FairQueue<TPayloadSchema extends z.ZodTypeAny = z.ZodUnknown> {
1994
2023
  private visibilityTimeoutMs;
1995
2024
  private heartbeatIntervalMs;
1996
2025
  private reclaimIntervalMs;
2026
+ private reconcileIntervalMs;
1997
2027
  private workerQueueResolver;
1998
2028
  private batchClaimSize;
1999
2029
  private cooloffEnabled;
@@ -2010,6 +2040,7 @@ declare class FairQueue<TPayloadSchema extends z.ZodTypeAny = z.ZodUnknown> {
2010
2040
  private abortController;
2011
2041
  private masterQueueConsumerLoops;
2012
2042
  private reclaimLoop?;
2043
+ private reconcileLoop?;
2013
2044
  private queueDescriptorCache;
2014
2045
  private tenantDispatch;
2015
2046
  constructor(options: FairQueueOptions<TPayloadSchema>);
package/dist/index.d.ts CHANGED
@@ -717,6 +717,8 @@ interface FairQueueOptions<TPayloadSchema extends z.ZodTypeAny = z.ZodUnknown> {
717
717
  heartbeatIntervalMs?: number;
718
718
  /** Interval for reclaiming timed-out messages (default: 5000) */
719
719
  reclaimIntervalMs?: number;
720
+ /** Interval for sweeping orphaned concurrency slots; 0 disables the sweep (default: 60000) */
721
+ reconcileIntervalMs?: number;
720
722
  /** Number of consumer loops to run (default: 1) */
721
723
  consumerCount?: number;
722
724
  /** Interval between consumer iterations in milliseconds (default: 100) */
@@ -915,6 +917,10 @@ interface ConcurrencyManagerOptions {
915
917
  redis: RedisOptions;
916
918
  keys: FairQueueKeyProducer;
917
919
  groups: ConcurrencyGroupConfig[];
920
+ logger?: {
921
+ debug: (message: string, context?: Record<string, unknown>) => void;
922
+ error: (message: string, context?: Record<string, unknown>) => void;
923
+ };
918
924
  }
919
925
  /**
920
926
  * ConcurrencyManager handles multi-level concurrency tracking and limiting.
@@ -931,6 +937,7 @@ declare class ConcurrencyManager {
931
937
  private keys;
932
938
  private groups;
933
939
  private groupsByName;
940
+ private logger;
934
941
  constructor(options: ConcurrencyManagerOptions);
935
942
  /**
936
943
  * Check if a message can be processed given all concurrency constraints.
@@ -956,6 +963,24 @@ declare class ConcurrencyManager {
956
963
  queue: QueueDescriptor;
957
964
  messageId: string;
958
965
  }>): Promise<void>;
966
+ /**
967
+ * Remove concurrency set members that no longer correspond to an in-flight message,
968
+ * healing slots leaked by failed releases. Scans every set of every group and, per
969
+ * member, atomically removes it unless the message id appears in one of the given
970
+ * in-flight data hashes. Sound because a message is registered in-flight before its
971
+ * slot is reserved, so at the moment of the atomic check a member with no in-flight
972
+ * record can only be a leak; if the message is about to be re-claimed, reserve simply
973
+ * re-adds the member.
974
+ *
975
+ * @param inflightDataKeys - The in-flight data hash keys for every shard. The sweep
976
+ * refuses to run when this is empty, since with nowhere to look for running messages
977
+ * every member would look orphaned and all concurrency accounting would be erased.
978
+ * @returns The message ids that were removed, and how many sets were checked
979
+ */
980
+ sweepOrphanedSlots(inflightDataKeys: string[]): Promise<{
981
+ scannedSets: number;
982
+ removed: string[];
983
+ }>;
959
984
  /**
960
985
  * Get current concurrency for a specific group.
961
986
  */
@@ -1003,6 +1028,7 @@ declare class ConcurrencyManager {
1003
1028
  declare module "@internal/redis" {
1004
1029
  interface RedisCommander<Context> {
1005
1030
  reserveConcurrency(numKeys: number, keys: string[], messageId: string, ...limits: string[]): Promise<number>;
1031
+ removeOrphanedConcurrencySlots(numKeys: number, keys: string[], ...messageIds: string[]): Promise<string[]>;
1006
1032
  }
1007
1033
  }
1008
1034
  //#endregion
@@ -1811,7 +1837,10 @@ declare class VisibilityManager {
1811
1837
  *
1812
1838
  * @param shardId - The shard to check
1813
1839
  * @param getQueueKeys - Function to get queue keys for a queue ID
1814
- * @returns Array of reclaimed message info for concurrency release
1840
+ * @param onBeforeRequeue - Hook invoked with the batch before any message is requeued,
1841
+ * used to free concurrency slots. A throw aborts the whole batch, leaving the
1842
+ * messages in-flight for the next reclaim tick.
1843
+ * @returns Array of reclaimed message info
1815
1844
  */
1816
1845
  reclaimTimedOut(shardId: number, getQueueKeys: (queueId: string) => {
1817
1846
  queueKey: string;
@@ -1819,7 +1848,7 @@ declare class VisibilityManager {
1819
1848
  tenantQueueIndexKey: string;
1820
1849
  dispatchKey: string;
1821
1850
  tenantId: string;
1822
- }): Promise<ReclaimedMessageInfo[]>;
1851
+ }, onBeforeRequeue?: (messages: ReclaimedMessageInfo[]) => Promise<void>): Promise<ReclaimedMessageInfo[]>;
1823
1852
  /**
1824
1853
  * Get all in-flight messages for a shard.
1825
1854
  */
@@ -1994,6 +2023,7 @@ declare class FairQueue<TPayloadSchema extends z.ZodTypeAny = z.ZodUnknown> {
1994
2023
  private visibilityTimeoutMs;
1995
2024
  private heartbeatIntervalMs;
1996
2025
  private reclaimIntervalMs;
2026
+ private reconcileIntervalMs;
1997
2027
  private workerQueueResolver;
1998
2028
  private batchClaimSize;
1999
2029
  private cooloffEnabled;
@@ -2010,6 +2040,7 @@ declare class FairQueue<TPayloadSchema extends z.ZodTypeAny = z.ZodUnknown> {
2010
2040
  private abortController;
2011
2041
  private masterQueueConsumerLoops;
2012
2042
  private reclaimLoop?;
2043
+ private reconcileLoop?;
2013
2044
  private queueDescriptorCache;
2014
2045
  private tenantDispatch;
2015
2046
  constructor(options: FairQueueOptions<TPayloadSchema>);