Weave 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

Async Laravel Package

php-standard-library/async

Fiber-based async primitives for PHP: structured concurrency with cooperative multitasking. Run tasks concurrently, manage lifecycles, cancellations, and scopes predictably. Part of PHP Standard Library; docs and guides at php-standard-library.dev.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Laravel Synergy: The package’s fiber-based structured concurrency complements Laravel’s synchronous defaults while enabling non-blocking I/O (e.g., parallel API calls, async database queries). It bridges the gap between Laravel’s queue system and true async execution, ideal for:
    • API Aggregators: Fetching multiple endpoints in parallel (e.g., Async::parallel()).
    • Background Processing: Offloading CPU/I/O-bound tasks (e.g., image resizing, batch imports) without blocking the request lifecycle.
    • Event-Driven Workflows: Orchestrating async event handlers (e.g., webhooks, notifications) with Async::onEvent()-like patterns.
  • Hybrid Sync/Async: Works alongside Laravel’s native Promise (Laravel 8+) and queue system, enabling gradual adoption. For example:
    • Use Async::task() for short-lived async operations in controllers.
    • Fall back to queues (dispatch()) for long-running or distributed tasks.
  • Middleware Integration: Can be used in async middleware (Laravel 11+) to process requests concurrently, though this requires careful error handling to avoid silent failures.

Integration Feasibility

  • Low-Coupling Design: The package’s minimal dependencies (only PHP 8.1+) and lack of Laravel-specific assumptions make it easy to integrate without modifying core Laravel files. Key integration points:
    • Service Container: Bind Async to Laravel’s DI container for dependency injection.
    • Facade Pattern: Create a Async facade (e.g., Async::task()) to match Laravel’s conventions.
    • Queue Integration: Use Async::later() to defer tasks to Laravel’s queue system for distributed execution.
  • Promise Compatibility: While Laravel 8+ includes Illuminate\Support\Facades\Promise, this package’s implementation may differ in:
    • Error Handling: Test how uncaught Promise rejections are logged (via Laravel’s App\Exceptions\Handler).
    • Chaining Syntax: Ensure Async::then()/Async::catch() align with team preferences (e.g., vs. spatie/async).
  • Database Considerations:
    • Risk: Async database operations (e.g., DB::async()) can leak connections or corrupt transactions. Mitigation:
      • Use DB::connection()->getPdo() for async queries.
      • Offload to queues for non-trivial DB work.
    • Alternative: Use Async::task() to wrap queue jobs (e.g., Async::task(fn() => ProcessPaymentJob::dispatch($data))).

Technical Risk

  • Blocking the Event Loop: Laravel’s synchronous layers (e.g., routes, middleware) can deadlock if async operations block the main thread. Mitigations:
    • Request Context: Restrict Async::run() to background jobs or async middleware.
    • Timeouts: Add Async::timeout(5) to prevent hanging.
  • Error Propagation: Async errors (e.g., rejected Promises) may not bubble up as expected. Test Cases:
    • A Promise rejecting after the response is sent (use Async::catch()).
    • Mixed sync/async code paths (e.g., async middleware throwing an exception).
  • Testing Complexity: Async workflows introduce flakiness. Solutions:
    • Use Async::fake() (if provided) or mock Async in tests:
      Async::shouldReceive('task')->andReturn(new MockPromise());
      
    • Test with Laravel’s refreshDatabase() and async seeders.
  • Dependency Conflicts: No direct conflicts, but ensure compatibility with:
    • spatie/async or amphp/async (avoid duplication).
    • Laravel’s illuminate/support (Promise facades).

Key Questions

  1. Use Case Prioritization:
    • Will this replace Laravel’s queue system, or supplement it? (Example: Use Async for short-lived tasks, queues for long-running ones.)
    • Is the primary goal performance (e.g., reducing latency in API aggregators) or code clarity (e.g., avoiding callback hell)?
  2. Performance Benchmarks:
    • Compare throughput/latency against:
      • Native queue workers (Illuminate\Queue).
      • spatie/async or Swoole for high-concurrency scenarios.
    • Measure memory usage (async tasks consume RAM until awaited).
  3. Adoption Strategy:
    • Start with non-critical paths (e.g., background jobs, CLI commands).
    • Document anti-patterns (e.g., mixing Async::run() in middleware without error handling).
  4. Long-Term Viability:
    • The package’s lack of stars/release history raises maintenance concerns. Plan for:
      • Forking if inactive.
      • Migrating to Laravel’s native async features (e.g., Laravel 11+).
    • Does it align with PHP’s async ecosystem (e.g., Swoole, ReactPHP)?

Integration Approach

Stack Fit

  • Laravel Core:
    • Queues: Use for fire-and-forget tasks (e.g., Async::later() → dispatch()).
    • Promises: Leverage illuminate/support for hybrid sync/async code (e.g., Async::task() → Promise::all()).
    • Events: Async event listeners (e.g., Async::onEvent()).
  • Async Runtimes:
    • Swoole: For true concurrency (package may need Swoole-specific adapters, e.g., Async::withSwoole()).
    • ReactPHP: If using react/promise, test compatibility (e.g., Async::fromReactPromise()).
    • Native PHP: For cooperative multitasking (e.g., Async::parallel()).
  • Third-Party:
    • Avoid Duplication: Prefer one async library (e.g., spatie/async or this package).
    • Amphp: If using Amphp’s event loop, ensure compatibility (e.g., Async::withAmphp()).

Migration Path

  1. Phase 1: Proof of Concept (1–2 weeks)

    • Replace a simple queue job with Async::task() to validate gains.
    • Example:
      // Before: Queue job
      ProcessPaymentJob::dispatch($userId);
      
      // After: Async task (in a controller)
      Async::task(fn() => ProcessPayment::run($userId))->await();
      
    • Success Metric: 20–30% faster response time for the target workflow.
  2. Phase 2: Composable Workflows (2–3 weeks)

    • Use Async::parallel() for fan-out (e.g., API aggregators):
      $results = Async::parallel([
          fn() => fetchUserData($userId),
          fn() => fetchOrderData($orderId),
      ])->await();
      
    • Replace nested callbacks with Async::then()/Async::catch():
      Async::task($task)
          ->then(fn($result) => log($result))
          ->catch(fn($e) => report($e));
      
    • Integration: Bind to Laravel’s container:
      $this->app->singleton(Async::class, fn() => new Async());
      
  3. Phase 3: Request Pipeline (3–4 weeks)

    • Caution: Only use in async middleware or Laravel 11+ async routes.
    • Example middleware:
      public function handle(Request $request, Closure $next) {
          return Async::run(fn() => $next($request))
              ->then(fn(Response $response) => $response)
              ->catch(fn(Throwable $e) => abort(500, $e->getMessage()));
      }
      
    • Testing: Load test with laravel-shift/async-testing or custom scripts.
  4. Phase 4: Observability (Ongoing)

    • Integrate with Laravel’s monitoring:
      • Log Async task durations in Sentry/New Relic.
      • Add Async::debug() middleware for development.
    • Example:
      Async::task($task)
          ->then(fn() => Log::debug('Task completed'))
          ->catch(fn($e) => Log::error('Task failed', ['error' => $e]));
      

Compatibility

  • Laravel Versions:
    • Target: Laravel 10/11 (Promise support, async routes).
    • Avoid: Laravel <8 (no native Promise facades).
  • PHP Extensions:
    • Required: PHP 8.1+ (for fibers, typed properties).
    • Optional:
      • Swoole: For high-performance use cases (package may need adapters).
      • ReactPHP: If using react/promise (test compatibility).
  • Database:
    • Do Not Use: Async DB queries in request context (connection leaks).
    • Safe Alternatives:
      • Wrap in queues: `Async::task(fn() => ProcessDataJob
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.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
adachsoft/php-code-style