class SyncContactJob < ApplicationJob
queue_as :external
BACKOFF = ->(executions) do
(2**executions) + rand(0.0..1.0) # exponential + jitter, in seconds
end
package httpretry
import (
"math/rand"
"time"
)
use std::time::Duration;
use rand::Rng;
#[derive(Clone, Debug)]
pub struct BackoffPolicy {
pub base_delay: Duration,
import random
from dataclasses import dataclass
from typing import Iterator
@dataclass(frozen=True)
package com.example.health;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;
const RETRYABLE_STATUS = new Set([408, 429, 500, 502, 503, 504]);
export function isRetryable(error: unknown, response?: Response): boolean {
if (response) {
return RETRYABLE_STATUS.has(response.status);
}
import java.time.Duration;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.Predicate;
public final class RetryPolicy {
private final int maxAttempts;
class CircuitBreaker
class CircuitOpenError < StandardError; end
def initialize(name, redis: Redis.current, failure_threshold: 5, failure_window: 60, cooldown: 30)
@key = "circuit:#{name}"
@redis = redis
const RETRYABLE_STATUS = new Set([408, 429, 500, 502, 503, 504]);
export function fullJitter(attempt, baseDelay = 300, maxDelay = 10_000) {
const ceiling = Math.min(maxDelay, baseDelay * 2 ** attempt);
return Math.random() * ceiling;
}