Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Sync Laravel Package

amphp/sync

Async synchronization primitives for Amp PHP: mutexes, semaphores, locks, and a synchronized helper. Coordinate concurrent fibers, ensure mutual exclusion, and cap parallel work (e.g., limit HTTP requests) with simple, safe abstractions.

View on GitHub
Deep Wiki
Context7

Getting Started

Install with composer require amphp/sync. Start with the synchronized() helper and LocalMutex for per-process concurrency control in async code — e.g., protecting a shared in-memory resource like a cache object or counter across fibers. For a first real-world use case, wrap a critical section in your HTTP client that writes to a log or updates a rate-limit counter. The simplest intro is:

use Amp\Sync\LocalMutex;
use function Amp\Sync\synchronized;

$mutex = new LocalMutex();
$counter = 0;

// Safely increment across concurrent coroutines
$increment = function () use (&$counter, $mutex) {
    synchronized($mutex, static function () use (&$counter) {
        $tmp = $counter;
        // Simulate non-atomic read/write
        $counter = $tmp + 1;
    });
};

Look first at the README’s Mutex and Semaphore sections — they’re the most frequently used primitives and directly replace volatile-style thinking in PHP.

Implementation Patterns

  • Rate limiting & request throttling: Use Semaphore with a count to limit concurrency (e.g., 5 concurrent API calls). Wrap async operations like HttpClient::request() in synchronized() or use acquire()/release() for more control. Prefer amphp/pipeline for high-level batch processing — it composes well with Sync\Semaphore for back-pressure.
  • Shared in-memory state: LocalParcel is ideal for sharing simple values (int, string, array) across coroutines without locking mistakes. Wrap read/write logic in parcel->synchronized() callbacks — the mutex used internally ensures safe mutation.
  • Inter-process communication: For cross-process safety:
    • Use SharedMemoryParcel (requires ext-shmop, ext-sysvsem) for fast shared memory on the same host.
    • Use RedisParcel (with amphp/redis) for distributed locking and coordination.
    • Use createChannelPair() for full-duplex messaging between parent and child processes (e.g., in amphp/parallel workers).
  • Durable locking: When Local* primitives aren’t enough, reach for RedisMutex or SharedMemoryMutex — but ensure your external store (Redis) is resilient and latency-tolerant.

Gotchas and Tips

  • Never block inside synchronized() callbacks: While synchronized() hides lock acquisition/release, blocking I/O inside it defeats the purpose. Always use async functions (Amp\File\write, etc.) inside.
  • Reentrancy is safe: Since v2.1, synchronized() supports reentry — calling synchronized() again from within the same callback with the same mutex is fine. Still, avoid deep nesting to prevent confusion.
  • Mutex vs Semaphore: A Mutex is just a Semaphore with count=1. If you need “only one at a time”, use Mutex. If you need “up to N concurrent” (e.g., connection pool), use Semaphore.
  • Local vs Shared variants: Local* primitives (e.g., LocalMutex, LocalSemaphore) only work within a single PHP process. For cross-process or distributed systems, use the *Mutex/*Semaphore variants backed by Redis, shared memory, or files — and test failing dependency paths (e.g., Redis down).
  • Back pressure with channels: Use createChannelPair($bufferSize) with StreamChannel or ProcessContext to avoid unbounded buffering. Buffer size matters — too large risks OOM, too small causes deadlock under load.
  • Upgrade path: If stuck on v1.x, be aware FileMutex, ThreadedMutex, and ConcurrentIterator helpers are gone in v2+. Migrate FileMutex to amphp/file and use amphp/pipeline instead of ConcurrentIterator functions.
  • Debugging tips: Set AMPHP_SYNC_DEBUG=1 as an environment variable (if supported by underlying primitives), or log spl_object_id() of locks to trace acquisition/release flow. Enable Redis/IPC error logging if using external stores.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport