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

P Service Bus Laravel Package

gdx/p-service-bus

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require gdx/p-service-bus
    

    Add the service provider to config/app.php:

    'providers' => [
        // ...
        GDX\PServiceBus\ServiceBusServiceProvider::class,
    ],
    
  2. Basic Configuration Publish the config file:

    php artisan vendor:publish --provider="GDX\PServiceBus\ServiceBusServiceProvider" --tag="config"
    

    Edit config/pservicebus.php to define your bus (e.g., default):

    'default' => [
        'driver' => 'sync', // or 'async', 'queue', etc.
        'options' => [
            // Driver-specific config (e.g., queue connection for 'queue' driver)
        ],
    ],
    
  3. First Use Case: Dispatching a Command Define a command:

    namespace App\Commands;
    
    use GDX\PServiceBus\Contracts\Command;
    
    class CreateUser implements Command
    {
        public function __construct(public string $name, public string $email) {}
    }
    

    Dispatch it in a controller or service:

    use GDX\PServiceBus\Facades\ServiceBus;
    
    ServiceBus::dispatch(new CreateUser('John Doe', '[email protected]'));
    
  4. Handling Commands Register a handler in a service provider:

    $this->app->bind(
        GDX\PServiceBus\Contracts\Handler::class,
        App\Handlers\CreateUserHandler::class
    );
    

    Implement the handler:

    namespace App\Handlers;
    
    use App\Commands\CreateUser;
    use GDX\PServiceBus\Contracts\Handler;
    
    class CreateUserHandler implements Handler
    {
        public function handle(CreateUser $command)
        {
            // Business logic here
            return true;
        }
    }
    

Implementation Patterns

Workflow: Command-Handler Pipeline

  1. Dispatching Use ServiceBus::dispatch() for synchronous execution or ServiceBus::dispatchAsync() for background processing.

    // Sync (blocks until handled)
    $result = ServiceBus::dispatch(new Command());
    
    // Async (non-blocking)
    ServiceBus::dispatchAsync(new Command());
    
  2. Middleware Integration Apply middleware to commands globally or per-command:

    // Global middleware (in ServiceBusServiceProvider)
    $this->app->make('pservicebus')->middleware([
        \App\Middleware\LogCommand::class,
        \App\Middleware\ValidateCommand::class,
    ]);
    
    // Per-command middleware
    ServiceBus::dispatch(new Command())
        ->withMiddleware([\App\Middleware\CustomMiddleware::class]);
    
  3. Event-Driven Extensions Listen for bus events (e.g., CommandDispatched, CommandHandled):

    // In a service provider
    event(new \GDX\PServiceBus\Events\CommandDispatched($command));
    
  4. Testing Mock the bus in tests:

    $bus = Mockery::mock('overload', \GDX\PServiceBus\Facades\ServiceBus::class);
    $bus->shouldReceive('dispatch')->once()->withArgs([$command]);
    

Integration Tips

  • Laravel Queues: For async drivers, configure the queue connection in pservicebus.php:
    'async' => [
        'driver' => 'queue',
        'options' => [
            'connection' => 'redis',
            'queue' => 'commands',
        ],
    ],
    
  • Retry Logic: Use Laravel’s retry mechanism with the queue driver:
    'queue' => [
        'options' => [
            'retry_after' => 60, // Retry after 60 seconds
        ],
    ],
    
  • Dependency Injection: Resolve handlers dynamically:
    $handler = app()->make(\GDX\PServiceBus\Contracts\Handler::class);
    $handler->handle($command);
    

Gotchas and Tips

Pitfalls

  1. Handler Registration

    • Issue: Handlers not found if not bound in a service provider.
    • Fix: Ensure handlers are registered in AppServiceProvider or a dedicated provider:
      $this->app->bind(
          \GDX\PServiceBus\Contracts\Handler::class,
          App\Handlers\{CommandName}Handler::class
      );
      
    • Tip: Use interfaces for handlers to enforce consistency:
      interface CreateUserHandlerInterface extends Handler {}
      
  2. Async Driver Quirks

    • Issue: Async commands may fail silently if the queue worker crashes.
    • Fix: Monitor queue jobs and implement dead-letter queues:
      'queue' => [
          'options' => [
              'queue' => 'commands',
              'fail_queue' => 'commands.failed',
          ],
      ],
      
  3. Middleware Order

    • Issue: Middleware may not execute in the expected order.
    • Fix: Use ->before() and ->after() for explicit ordering:
      ServiceBus::dispatch(new Command())
          ->withMiddleware([
              \App\Middleware\First::class,
          ])
          ->before(\App\Middleware\PreValidation::class)
          ->after(\App\Middleware\PostLogging::class);
      
  4. Circular Dependencies

    • Issue: Commands dispatching other commands can cause infinite loops.
    • Fix: Use a Bus facade or container to avoid direct instantiation:
      // Bad: Direct instantiation
      $bus = new \GDX\PServiceBus\Bus();
      
      // Good: Use facade
      ServiceBus::dispatch(new NestedCommand());
      

Debugging

  • Log Dispatches: Enable debug mode in pservicebus.php:
    'debug' => env('PSERVICEBUS_DEBUG', false),
    
  • Command Tracing: Use Laravel’s logging to trace command flow:
    use Illuminate\Support\Facades\Log;
    
    class CreateUserHandler implements Handler
    {
        public function handle(CreateUser $command)
        {
            Log::debug('Handling CreateUser', ['command' => $command]);
            // ...
        }
    }
    

Extension Points

  1. Custom Drivers Extend the Driver interface to support new transport layers (e.g., gRPC, Kafka):

    namespace App\Drivers;
    
    use GDX\PServiceBus\Contracts\Driver;
    
    class GrpcDriver implements Driver
    {
        public function dispatch($command) { /* ... */ }
        public function dispatchAsync($command) { /* ... */ }
    }
    

    Register it in pservicebus.php:

    'grpc' => [
        'driver' => \App\Drivers\GrpcDriver::class,
        'options' => [...],
    ],
    
  2. Command Validation Use Laravel’s validation pipeline:

    namespace App\Middleware;
    
    use Closure;
    use Illuminate\Validation\ValidationException;
    
    class ValidateCommand
    {
        public function handle($command, Closure $next)
        {
            $validator = validator($command, [
                'email' => 'required|email',
            ]);
    
            if ($validator->fails()) {
                throw new ValidationException($validator);
            }
    
            return $next($command);
        }
    }
    
  3. Performance Optimization

    • Batch Processing: For bulk commands, use ServiceBus::dispatchBatch() (if supported).
    • Caching Handlers: Cache handler instances if commands are frequently repeated:
      $handler = app()->makeWith(\App\Handlers\CreateUserHandler::class);
      
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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo