Skip to content

About

PHP component for application resilience

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

sidebar_key resilience
tags
php
concurrency

Resilience

Utilities for the two things that go wrong when work is spread across processes: something is not ready yet, and something must only happen once.

Sponsor Build Status Opensource ByJG Install MCP Server GitHub source GitHub license GitHub release

Key Features

  • Exponential backoff - poll for a value with a growing delay and a real ceiling on total wait time
  • Distributed mutex - a named lock with owner tokens and TTL-based crash recovery
  • Pluggable lock stores - built on an atomic compare-and-swap contract, not on best-effort caching
  • Attribute-driven - attach either policy declaratively to a method
  • Testable timing - injectable clock and sleep, so multi-second policies verify in virtual time

Quick Start

Wait for something that is not there yet:

use ByJG\Resilience\ExponentialBackoffWaiter;

$waiter = new ExponentialBackoffWaiter(
    initialDelayMicros: 200_000,   // 200ms
    maxTotalWaitMicros: 3_500_000, // 3.5s
    multiplier: 2.0
);

$reward = $waiter->wait(fn() => $rewardRepo->get($id));

Make sure something happens only once:

use ByJG\Cache\Psr16\RedisCacheEngine;
use ByJG\Resilience\Lock\CacheEngineLockStore;
use ByJG\Resilience\Mutex;

$mutex = new Mutex(new CacheEngineLockStore(new RedisCacheEngine()));

$result = $mutex->execute('rebuild-report', fn() => rebuildTheReport(), ttlSeconds: 60);

Documentation

  • Exponential Backoff - the waiter, its timing guarantees, and testing it
  • Mutex - acquiring, releasing, refreshing, and choosing a TTL
  • Lock Stores - the store contract, the shipped adapter, and what a lock does not guarantee
  • Attributes - #[ExponentialBackoff] and #[Mutex] with their executors

Requirements

PHP 8.3 or later.

The Mutex needs a store that can perform an atomic set-if-absent. The shipped adapter covers byjg/cache-engine engines backed by Redis or Memcached:

composer require byjg/cache-engine

A plain PSR-16 cache is deliberately not accepted — see Lock Stores for why.

Installation

composer require byjg/resilience

Running Tests

vendor/bin/phpunit

Tests covering the lock stores need Redis and Memcached, and skip cleanly when they are absent:

docker compose up -d
vendor/bin/phpunit
docker compose down

Open source ByJG

About

PHP component for application resilience

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages