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

Pokio Laravel Package

nunomaduro/pokio

Pokio is a minimal async API for PHP. Run closures concurrently using PCNTL forking and shared-memory IPC via FFI, then await results like promises. Built for internal tooling/perf work (e.g., Pest). Not production-safe; use at your own risk.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require nunomaduro/pokio
    

    Requires PHP 8.3+ and automatically falls back to sequential execution if PCNTL or FFI are unavailable.

  2. First Use Case: Replace a blocking sleep() or sequential I/O operation with parallel execution:

    $promiseA = async(function () {
        sleep(2);
        return 'Task A';
    });
    
    $promiseB = async(function () {
        sleep(2);
        return 'Task B';
    });
    
    [$resultA, $resultB] = await([$promiseA, $promiseB]);
    // Both tasks complete in ~2 seconds (not 4)
    
  3. Where to Look First:

    • async(): Wrap any function or closure to run asynchronously.
    • await(): Block until a promise (or array of promises) resolves.
    • Promise chaining: Use then(), catch(), and finally() for async workflows.

Implementation Patterns

Core Workflows

1. Parallelizing I/O-Bound Tasks

Use Case: Speed up CLI scripts with API calls, DB queries, or file operations.

$apiCalls = [
    async(fn() => Http::get('api/users')),
    async(fn() => Http::get('api/posts')),
];
[$users, $posts] = await($apiCalls);

Laravel Integration:

$promise = async(function () {
    return DB::table('users')->where('active', true)->get();
});
$activeUsers = await($promise);

2. Error Handling

Pattern: Use catch() or try/catch for graceful failures.

$promise = async(fn() => Http::get('api/unreachable'))
    ->catch(fn(Throwable $e) => ['error' => $e->getMessage()]);
$result = await($promise);

Global Fallback:

try {
    await($promise);
} catch (Throwable $e) {
    Log::error('Async task failed:', ['error' => $e]);
    return fallbackData();
}

3. Chaining Promises

Use Case: Transform or depend on async results sequentially.

$promise = async(fn() => fetchData())
    ->then(fn($data) => processData($data))
    ->then(fn($processed) => saveToDB($processed));
await($promise);

4. Resource Cleanup

Pattern: Use finally() for cleanup (e.g., DB transactions, file locks).

$promise = async(function () {
    DB::beginTransaction();
    // ... operations ...
})->finally(function () {
    DB::commit(); // or rollBack()
});
await($promise);

5. Invokable Promises

Shortcut: Call a promise directly to get its resolved value.

$promise = async(fn() => 1 + 1);
$result = $promise(); // int(2)

6. Nested Promises

Use Case: Return promises from async closures to chain async operations.

$promise = async(function () {
    return async(fn() => fetchUser(1));
});
$user = await($promise); // awaits the nested promise

7. Parallelizing Artisan Commands

Advanced: Run multiple Artisan commands in parallel (e.g., migrations + reports).

$promises = [
    async(fn() => Artisan::call('migrate')),
    async(fn() => Artisan::call('db:seed')),
];
await($promises);

8. Testing with Pest

Use Case: Speed up test suites with parallel test execution.

async(fn() => test('User creation', fn() => /* ... */));
async(fn() => test('User deletion', fn() => /* ... */));
await([$test1, $test2]);

Integration Tips

Laravel-Specific

  • Service Providers: Register Pokio as a singleton if needed (though globals are preferred).
  • Commands: Use in Artisan::command() methods for parallelized CLI logic.
  • Jobs: Avoid mixing with Laravel Queues (Pokio is for short-lived, in-process tasks).

Debugging

  • Xdebug Compatibility: Pokio auto-disables forking in Xdebug debug mode (no config needed).
  • Debugging Async Code:
    $promise = async(fn() => debugData())
        ->then(fn($data) => debug($data));
    await($promise);
    

Fallbacks

  • Missing Extensions: Pokio falls back to sequential execution if PCNTL/FFI are unavailable.
  • Test Fallbacks:
    if (!extension_loaded('pcntl')) {
        $this->markTestSkipped('PCNTL not available');
    }
    

Performance

  • Avoid Overhead: Use for I/O-bound tasks (API calls, DB queries). CPU-bound tasks may not benefit.
  • Limit Concurrency: Avoid spawning too many child processes (default is safe for most use cases).

Gotchas and Tips

Pitfalls

  1. State Isolation:

    • Child processes do not share memory with the parent. Use shared storage (DB, files, Redis) for coordination.
    • Example: Avoid relying on global variables or static state across promises.
  2. Xdebug Conflicts:

    • Pokio auto-disables forking when Xdebug is in debug mode (no manual config needed).
    • Gotcha: If Xdebug is not in debug mode (e.g., xdebug.mode=coverage), forking works as expected.
  3. Long-Running Tasks:

    • Child processes may be killed by OS limits (e.g., ulimit).
    • Tip: Use for tasks <5 minutes. For longer tasks, use Laravel Queues or Swoole.
  4. Error Bubbling:

    • Uncaught exceptions in async closures do not crash the parent process but are caught by catch() or await blocks.
    • Tip: Always handle errors explicitly:
      await($promise->catch(fn(Throwable $e) => logError($e)));
      
  5. FFI/PCNTL Dependencies:

    • Pokio falls back to sequential execution if extensions are missing, but performance will degrade.
    • Tip: Test in your target environment:
      if (!Pokio::isSupported()) {
          throw new RuntimeException('Pokio not supported in this environment');
      }
      
  6. Shared Resources:

    • Database Connections: Child processes may reuse the parent’s connection pool. Use finally() to close connections:
      $promise = async(function () {
          $conn = DB::connection()->getPdo();
          // ... use $conn ...
      })->finally(fn() => DB::disconnect());
      
  7. File Handles:

    • Child processes inherit file handles. Avoid holding locks or open files across promises.
  8. Serialization:

    • Closures are serialized to pass to child processes. Avoid closures with unserializable objects (e.g., resources, DOM nodes).
    • Tip: Use simple data structures or ensure objects implement __serialize().
  9. Windows Support:

    • Pokio does not support Windows (relies on PCNTL/FFI, which are Unix-only).
    • Tip: Use sequential fallback or alternative tools (e.g., popen) on Windows.
  10. Memory Usage:

    • Each child process consumes additional memory. Monitor usage for high-concurrency scenarios.

Debugging Tips

  1. Check Support:

    if (!Pokio::isSupported()) {
        echo "Pokio not available (falling back to sequential).";
    }
    
  2. Log Promises:

    $promise = async(fn() => fetchData())
        ->then(fn($data) => Log::debug('Resolved:', ['data' => $data]));
    await($promise);
    
  3. Inspect Child Processes:

    • Use ps aux | grep php to monitor child processes during execution.
  4. Timeouts:

    • Add timeouts to prevent hanging:
      $promise = async(fn() => sleep(10))
          ->then(fn() => 'Done', 5000); // Reject if >5s
      await($promise);
      
  5. Xdebug Debugging:

    • Pokio works with Xdebug in debug mode, but child processes cannot be debugged directly.
    • Tip: Debug the parent process and log key steps in child processes.

Extension Points

  1. Custom Forking Logic:
    • Override Pokio\ForkManager to implement custom process handling (e.g., custom IPC).

2

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.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai