📘
@node-test/bus
  • @node-ts/bus
  • Getting started
    • Installation
    • Handling messages
    • Shutting down cleanly
  • Reference
    • Bus
    • BusConfiguration
    • BusInstance
  • Getting help
  • Guide
    • Messages
      • Events
      • Commands
      • System messages
    • Message attributes
      • Correlation id
      • Attributes
      • Sticky attributes
    • Workflows
      • Creating a workflow
      • Starting
      • Handling
      • State
      • Completing
      • Example
    • Transports
      • RabbitMQ
      • Amazon SQS
      • Redis
      • Custom transports
    • Persistence
      • Postgres
      • MongoDB
      • Creating a persistence
    • Serializers
      • Class serializer
    • Loggers
      • Custom loggers
    • Middleware
    • Lifecycle hooks
    • Retry Strategies
    • Dependency injection
    • Long running processes
Powered by GitBook
On this page
  • Choosing a Retry Strategy
  • Custom retry strategies

Was this helpful?

  1. Guide

Retry Strategies

Message retry strategies allow you to specify how much of a delay should occur before retrying a message.

Delays between retries can be useful when messages fail handling due to race conditions, service unavailability, or concurrency reasons.

By default, @node-ts/bus uses a DefaultRetryStrategy that exponentially increases the delay between each retry attempt. Additionally, it will introduce a random variance of 10% for each delay to help unblock messages that are failing when processed at the same time.

Additional strategies can be implemented to suit your application.

Choosing a Retry Strategy

A retry strategy can be provided to the bus configuration on initialization by using .withRetryStrategy()

For example:

const bus = await Bus.configure()
  .withRetryStrategy(DefaultRetryStrategy)
  .initialize()

Custom retry strategies

A custom retry strategy can be provided by implementing the RetryStrategy from @node-ts/bus-core.`

retry-strategy.ts
export type Milliseconds = number

/**
 * Defines how a message retry strategy is to be implemented that calculates the delay between subsequent
 * retries of a message.
 */
export interface RetryStrategy {
  /**
   * Calculate the delay between retrying a failed message
   * @param currentAttempt How many attempts at handling the message have failed
   * @returns The number of milliseconds to delay retrying a failed message attempt
   */
  calculateRetryDelay (currentAttempt: number): Milliseconds
}

An example of a retry strategy is as follows

default-retry-strategy.ts
import { Milliseconds, RetryStrategy } from './retry-strategy'

const MAX_DELAY_MS = 2.5 * 60 * 60 * 1000 // 2.5 hours
const JITTER_PERCENT = 0.1

/**
 * A default message retry strategy that exponentially increases the delay between retries
 * from 5ms to 2.5 hrs for the first 10 attempts. Each retry delay includes a jitter of
 * up to 10% to avoid deadlock-related errors from continually blocking.
 */
export class DefaultRetryStrategy implements RetryStrategy {
  calculateRetryDelay (currentAttempt: number): Milliseconds {
    const numberOfFailures = currentAttempt + 1
    const constantDelay: Milliseconds = Math.pow(5, numberOfFailures)
    
    const jitterAmount = Math.random() * JITTER_PERCENT * constantDelay
    const jitterDirection = Math.random() > 0.5 ? 1 : -1
    const jitter = jitterAmount * jitterDirection
    
    const delay = Math.round(constantDelay + jitter)
    return Math.min(delay, MAX_DELAY_MS)
  }
}

PreviousLifecycle hooksNextDependency injection

Last updated 3 years ago

Was this helpful?