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

Coroutine Laravel Package

hyperf/coroutine

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to First Use

  1. Prerequisites:

    • Install Hyperf (not Laravel) as hyperf/coroutine is designed for it.
    • Requires Swoole 5.0+ (PHP extension). Verify with:
      php -m | grep swoole
      
    • Composer install:
      composer require hyperf/coroutine
      
  2. First Coroutine: Create a simple coroutine in app/Command/Hello.php:

    namespace App\Command;
    
    use Hyperf\Command\Command as HyperfCommand;
    use Hyperf\AsyncQueue\Driver\RedisDriver;
    use Hyperf\Coroutine\Coroutine;
    
    class Hello extends HyperfCommand
    {
        protected function configure()
        {
            $this->setName('hello')->setDescription('Test coroutine');
        }
    
        public function handle()
        {
            Coroutine::create(function () {
                $this->output('Hello from coroutine!');
            });
        }
    }
    

    Run with:

    php bin/hyperf.php hello
    
  3. First Async I/O: Use Hyperf\HttpClient with coroutines for non-blocking HTTP calls:

    use Hyperf\HttpClient\Client;
    use Hyperf\Coroutine\Coroutine;
    
    Coroutine::create(function () {
        $client = new Client();
        $response = yield $client->get('https://httpbin.org/get');
        $this->output($response->body());
    });
    
  4. Key Files to Explore:

    • config/autoload/coroutine.php: Coroutine pool settings.
    • app/Listener/CoroutineListener.php: Example of coroutine event handling.
    • vendor/hyperf/coroutine/src: Core implementation (e.g., Coroutine.php, Channel.php).

Implementation Patterns

Core Workflows

1. Fire-and-Forget Tasks

Offload blocking operations (e.g., sending emails, processing files) to coroutines:

Coroutine::create(function () {
    // Simulate long-running task
    sleep(5);
    Mail::send('emails.welcome', [], function ($message) {
        $message->to('user@example.com');
    });
});

2. Cooperative Multitasking

Use yield to pause/resume coroutines for I/O-bound operations:

Coroutine::create(function () {
    $client = new Client();
    $response = yield $client->get('https://api.example.com/data');
    $data = json_decode($response->body(), true);
    // Process data...
});

3. Channel Communication

Pass data between coroutines using Channel:

$channel = new Channel(10);
Coroutine::create(function () use ($channel) {
    $channel->push('data from coroutine');
});

Coroutine::create(function () use ($channel) {
    $data = yield $channel->pop();
    $this->output($data);
});

4. Worker Pools

Limit concurrency with CoroutinePool:

$pool = new CoroutinePool(5); // Max 5 concurrent coroutines
for ($i = 0; $i < 10; $i++) {
    $pool->append(function () {
        // Task logic
    });
}
$pool->wait();

5. Integration with Hyperf Components

  • HTTP Server: Handle WebSocket connections asynchronously:
    use Hyperf\WebSocketServer\Event;
    
    $server->on('message', function (Event $event) {
        Coroutine::create(function () use ($event) {
            // Process message asynchronously
            $event->send('pong');
        });
    });
    
  • Task Queue: Offload queue workers to coroutines:
    $queue = new AsyncQueue(new RedisDriver());
    $queue->push(new SendEmailTask($user));
    

Laravel Integration Tips (Advanced)

If using Lumen + Swoole, bridge Laravel services to Hyperf coroutines:

  1. Dependency Injection:

    $container = new Container();
    $container->bind('mailer', function () {
        return new LaravelMailer(); // Custom wrapper
    });
    Coroutine::create(function () use ($container) {
        $mailer = $container->make('mailer');
        $mailer->send(...);
    });
    
  2. Middleware Adaptation: Convert Laravel middleware to Hyperf-style coroutine middleware:

    $middleware = new CoroutineMiddleware(function ($request, $next) {
        return Coroutine::create(function () use ($request, $next) {
            return yield $next($request);
        });
    });
    
  3. Database: Use hyperf/db-connection for async queries:

    Coroutine::create(function () {
        $user = yield DB::connection()->table('users')->where('id', 1)->first();
    });
    

Gotchas and Tips

Pitfalls

  1. Blocking the Event Loop:

    • Never call blocking functions (e.g., file_get_contents(), sleep()) directly in coroutines without yield.
    • Fix: Use Coroutine::sleep() or yield with async alternatives:
      // Bad: Blocks the coroutine
      sleep(1);
      
      // Good: Non-blocking
      yield Coroutine::sleep(1);
      
  2. Shared State Race Conditions:

    • Coroutines share memory; avoid mutable static variables or global state.
    • Fix: Use Channel or Lock for synchronization:
      $lock = new Lock();
      Coroutine::create(function () use ($lock) {
          $lock->acquire();
          // Critical section
          $lock->release();
      });
      
  3. Uncaught Exceptions:

    • Unhandled exceptions in coroutines may crash the process.
    • Fix: Wrap coroutines in try-catch or use Coroutine::create() with error handling:
      Coroutine::create(function () {
          try {
              // Risky code
          } catch (\Throwable $e) {
              Logger::error($e);
          }
      });
      
  4. Resource Leaks:

    • Coroutines that never complete (e.g., infinite loops) leak resources.
    • Fix: Use timeouts or Coroutine::cancel():
      $coroutine = Coroutine::create(function () {
          while (true) {
              yield Coroutine::sleep(1);
          }
      });
      $coroutine->cancel(); // Terminate if needed
      
  5. Laravel-Specific Issues:

    • Eloquent: Not coroutine-safe by default. Use hyperf/db-connection or raw queries.
    • Cache: Laravel’s cache drivers may block. Use hyperf/cache or Redis directly.
    • Events: Laravel’s event system is synchronous. Use Hyperf’s EventDispatcher for async events.

Debugging Tips

  1. Stack Traces: Coroutine stack traces are fragmented. Use Coroutine::getContext() to inspect state:

    Coroutine::create(function () {
        $context = Coroutine::getContext();
        Logger::info('Coroutine ID:', $context['id']);
    });
    
  2. Logging: Log coroutine IDs for tracking:

    Coroutine::create(function () {
        $id = Coroutine::id();
        Logger::info("Coroutine {$id} started");
        // ...
        Logger::info("Coroutine {$id} finished");
    });
    
  3. Profiling: Use Hyperf’s built-in profiler or integrate with XHProf:

    Coroutine::create(function () {
        $profiler = new Profiler();
        $profiler->start('coroutine_task');
        // Task logic
        $profiler->stop('coroutine_task');
    });
    
  4. Common Errors:

    • CoroutineException: Usually indicates a blocking call. Check for sleep(), file_get_contents(), or synchronous HTTP clients.
    • ChannelException: Likely a deadlock. Ensure producers/consumers are balanced.
    • SwooleException: Swoole-specific issues (e.g., invalid coroutine context). Verify Swoole version.

Configuration Quirks

  1. Pool Sizing:

    • Default pool size (config/autoload/coroutine.php) may need tuning:
      'pool' => [
          'max_coroutines' => 1000, // Adjust based on workload
          'max_stack_size' => 1024 * 1024, // 1MB stack per coroutine
      ],
      
    • Rule of Thumb: Start with max_coroutines = 2 * CPU cores for I/O-bound tasks.
  2. Timeouts:

    • Coroutines without yield may hang. Set timeouts:
      Cor
      
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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor