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

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

Getting Started

Minimal Steps

  1. Installation

    composer require php-standard-library/async
    

    No configuration required—just autoload.

  2. First Use Case: Parallel HTTP Requests

    use Async\Task;
    use Async\Promise;
    
    // Run multiple HTTP calls concurrently
    $promises = [
        Task::run(fn() => file_get_contents('https://api.example.com/data1')),
        Task::run(fn() => file_get_contents('https://api.example.com/data2')),
    ];
    
    // Await all results
    $results = Promise::all($promises);
    print_r($results);
    
  3. Where to Look First

    • Task class: Core primitive for wrapping async operations.
    • Promise class: For composing and awaiting results.
    • Async facade (if provided): Convenience methods for common patterns.
    • examples/ directory (if included in the package): Real-world snippets.

Implementation Patterns

Workflows

  1. Fan-Out/Fan-In Pattern

    $tasks = collect($urls)->map(fn($url) => Task::run(fn() => http_get($url)));
    $results = Promise::all($tasks); // Waits for all to complete
    
  2. Error Handling with Promise::any()

    $promises = [
        Task::run(fn() => riskyOperation1()),
        Task::run(fn() => riskyOperation2()),
    ];
    $firstSuccess = Promise::any($promises); // Resolves on first success
    
  3. Chaining Async Operations

    $result = Task::run(fn() => fetchData())
        ->then(fn($data) => processData($data))
        ->then(fn($processed) => saveToDb($processed));
    
  4. Integration with Laravel Queues

    // Dispatch a job asynchronously
    Task::run(fn() => dispatch(new ProcessPaymentJob($order)))
        ->then(fn() => logCompletion($order));
    

Integration Tips

  • Laravel Queue Integration: Use Task::run() to wrap dispatch() calls for async job execution.
    Task::run(fn() => dispatch(new LongRunningJob($data)));
    
  • Swoole/Preact Compatibility: If using Swoole/Preact, leverage their event loops with Async\EventLoop (if supported).
  • Database Transactions: Avoid mixing async tasks with DB transactions—use Task::run() outside transactions or implement retry logic.

Gotchas and Tips

Pitfalls

  1. Blocking the Event Loop: Avoid long-running synchronous code inside Task::run(). Use Task::delay() for timeouts or split work into smaller chunks.

    // ❌ Bad: Blocks the event loop
    Task::run(fn() => sleep(10));
    
    // ✅ Good: Use delays or async alternatives
    Task::delay(1000, fn() => doWork());
    
  2. Error Propagation: Unhandled exceptions in Task::run() will propagate to the Promise unless caught explicitly.

    // ❌ Silent failure
    Task::run(fn() => throw new RuntimeException());
    
    // ✅ Explicit error handling
    Task::run(fn() => riskyOperation())
        ->catch(fn(\Throwable $e) => logError($e));
    
  3. Stateful Closures: Closures passed to Task::run() may capture variables by reference, leading to race conditions.

    // ❌ Unpredictable state
    $counter = 0;
    Task::run(fn() => $counter++);
    
    // ✅ Use immutable data or locks
    Task::run(fn() => incrementCounter($counter));
    

Debugging

  • Log Task Execution: Use Task::run()->then(fn() => logger()->debug('Task completed')) to trace async flows.
  • Timeouts: Set timeouts with Task::run()->timeout(5000) (5 seconds) to avoid hanging.
  • Deadlocks: Avoid nested Promise::all() calls without proper error handling—use Promise::allSettled() for robustness.

Extension Points

  1. Custom Task Schedulers: Extend Async\Scheduler to integrate with custom queues (e.g., Redis, RabbitMQ).

    class CustomScheduler extends Scheduler {
        public function run(Closure $task) { /* ... */ }
    }
    
  2. Middleware for Tasks: Add pre/post-processing to tasks via decorators.

    $task = new Task(fn() => doWork());
    $task->pipe(new LoggingMiddleware());
    
  3. Promise Compositors: Create custom combinators (e.g., Promise::race(), Promise::reduce()) by extending Promise.

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
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
twbs/bootstrap4
php-http/client-implementation
phpcr/phpcr-implementation
cucumber/gherkin-monorepo
haydenpierce/class-finder
psr/simple-cache-implementation
uri-template/tests