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

Asynchronous Laravel Package

simple-bus/asynchronous

Generic PHP classes and interfaces for processing messages asynchronously with a SimpleBus MessageBus. Provides building blocks to queue, publish, and handle messages outside the request cycle; integrates with SimpleBus components and documented usage guides.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require simple-bus/asynchronous
    

    Ensure you already have simple-bus/message-bus installed (this package depends on it).

  2. Basic Configuration:

    • Require the package in your Laravel service provider:
      $this->app->bind(\SimpleBus\Asynchronous\Queue\QueueInterface::class, function ($app) {
          return new \SimpleBus\Asynchronous\Queue\LaravelQueue($app['queue']);
      });
      
  3. First Use Case:

    • Create a command handler that processes messages asynchronously:
      use SimpleBus\Asynchronous\Queue\QueueInterface;
      
      class AsyncCommandHandler
      {
          public function __construct(private QueueInterface $queue) {}
      
          public function handle(YourCommand $command)
          {
              $this->queue->dispatch(new AsyncMessage($command->data));
          }
      }
      
  4. Worker Setup:

    • Configure Laravel's queue worker to process SimpleBus\Asynchronous\Message:
      php artisan queue:work --queue=simplebus
      
    • Ensure your config/queue.php has a simplebus connection configured (e.g., database, redis, or sync).

Implementation Patterns

Core Workflow

  1. Dispatching Messages:

    • Use the QueueInterface to dispatch messages asynchronously:
      $this->queue->dispatch(new YourAsyncMessage($payload));
      
    • Wrap synchronous logic in a message class implementing SimpleBus\Message\Message.
  2. Message Design:

    • Messages should be immutable and serializable (e.g., using JsonSerializable or Arrayable).
    • Example:
      class SendEmailMessage implements \SimpleBus\Message\Message, \JsonSerializable
      {
          public function __construct(private string $email, private string $content) {}
      
          public function jsonSerialize(): array
          {
              return ['email' => $this->email, 'content' => $this->content];
          }
      }
      
  3. Handling Messages:

    • Create a handler for your async message:
      use SimpleBus\Asynchronous\Message\MessageHandler;
      
      class SendEmailHandler implements MessageHandler
      {
          public function handle(SendEmailMessage $message)
          {
              Mail::to($message->email)->send(new Email($message->content));
          }
      }
      
    • Register the handler with SimpleBus:
      $this->app->bind(\SimpleBus\MessageBus::class, function ($app) {
          $bus = new \SimpleBus\MessageBus([
              new \SimpleBus\Asynchronous\Message\MessageHandler(
                  new SendEmailHandler(),
                  SendEmailMessage::class
              ),
          ]);
          return $bus;
      });
      
      
  4. Integration with Laravel Jobs (Optional):

    • For complex workflows, combine with Laravel Jobs:
      class ProcessOrderJob implements ShouldQueue
      {
          use DispatchesJobs;
      
          public function handle()
          {
              $this->dispatch(new ProcessOrderMessage($orderId));
          }
      }
      
  5. Error Handling:

    • Use Laravel's queue failure callbacks to retry or notify:
      Queue::failCallback(function ($connection, $queue, $job, $exception) {
          Log::error("Async job failed: " . $exception->getMessage());
      });
      

Gotchas and Tips

Pitfalls

  1. Serialization Issues:

    • Non-serializable objects (e.g., closures, resources) will fail silently or throw errors.
    • Fix: Ensure all message properties are serializable (use JsonSerializable, Arrayable, or basic types).
  2. Queue Connection Mismatch:

    • If the QueueInterface is not bound to the correct Laravel queue connection, messages may disappear.
    • Fix: Explicitly configure the queue connection in the QueueInterface binding:
      $this->app->bind(\SimpleBus\Asynchronous\Queue\QueueInterface::class, function ($app) {
          return new \SimpleBus\Asynchronous\Queue\LaravelQueue($app['queue'], 'simplebus');
      });
      
  3. Handler Registration:

    • Forgetting to register message handlers with the MessageBus will result in unhandled messages.
    • Fix: Always bind handlers in your service provider or boot method:
      $bus->register(new \SimpleBus\Asynchronous\Message\MessageHandler(
          new YourHandler(),
          YourMessage::class
      ));
      
  4. Worker Stuck in Processing:

    • If a handler throws an exception, the worker may hang or retry indefinitely.
    • Fix: Use Laravel's queue retry logic or implement a custom ShouldQueue job wrapper.
  5. Testing Async Workflows:

    • Async messages are hard to test directly. Use Laravel's Queue::fake() and expectsJobs():
      public function test_async_message()
      {
          Queue::fake();
          $this->app->make(AsyncCommandHandler::class)->handle(new YourCommand());
          Queue::assertPushed(AsyncMessage::class);
      }
      

Tips

  1. Batch Processing:

    • For high-volume async tasks, batch messages using Laravel's batch():
      $this->queue->dispatchBatch([
          new AsyncMessage($data1),
          new AsyncMessage($data2),
      ]);
      
  2. Delayed Dispatch:

    • Use Laravel's delay() to schedule messages:
      $this->queue->dispatch(new AsyncMessage($data))->delay(now()->addMinutes(10));
      
  3. Monitoring:

    • Track async jobs with Laravel Horizon or a custom queue monitor:
      // Example: Log message dispatch
      $this->queue->dispatch(new AsyncMessage($data), function ($message) {
          Log::info("Dispatched async message: " . get_class($message));
      });
      
  4. Extending Functionality:

    • Create custom queue adapters for non-Laravel queues (e.g., RabbitMQ):
      class RabbitMqQueue implements QueueInterface
      {
          public function dispatch(Message $message, ?Closure $callback = null)
          {
              // Custom RabbitMQ logic
          }
      }
      
  5. Performance Tuning:

    • Adjust Laravel's queue worker batch size (--batch=N) for optimal throughput.
    • Use Redis for low-latency queues if database queues are a bottleneck.
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.
terminal42/code-quality-tools
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