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 Bundle Laravel Package

danilovl/async-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require danilovl/async-bundle
    

    Ensure Danilovl\AsyncBundle\AsyncBundle::class is registered in config/bundles.php.

  2. First Use Case: Inject the AsyncListener into a controller or service:

    use Danilovl\AsyncBundle\AsyncListener;
    
    public function __construct(private AsyncListener $asyncListener) {}
    
    public function handleRequest(): Response
    {
        // Execute async tasks after response
        $this->asyncListener->add(function () {
            // Your delayed logic (e.g., logging, queue creation)
            \Log::info('Async task executed');
        });
    
        return new Response('Response sent immediately!');
    }
    
  3. Key Files:

    • config/packages/async.yaml (if customization is needed).
    • src/AsyncListener (for direct usage).

Implementation Patterns

Core Workflow

  1. Trigger Async Tasks: Use AsyncListener::add() to queue closures or callables:

    $this->asyncListener->add(function () {
        // Heavy or non-critical logic
    });
    
  2. Dependency Injection: Prefer constructor injection for AsyncListener in services/controllers:

    public function __construct(private AsyncListener $asyncListener) {}
    
  3. Integration with Symfony Events: Attach async tasks to event listeners:

    $eventDispatcher->addListener(KernelEvents::RESPONSE, function (RequestEvent $event) {
        $this->asyncListener->add(function () {
            // Post-response logic
        });
    });
    
  4. Batch Processing: Group related async tasks in a single closure:

    $this->asyncListener->add(function () {
        $this->logAnalytics();
        $this->sendQueueMessage();
    });
    

Advanced Patterns

  • Async Services: Create dedicated services for async logic:

    class AsyncAnalyticsService {
        public function __construct(private AsyncListener $asyncListener) {}
    
        public function trackEvent(string $event): void {
            $this->asyncListener->add(function () use ($event) {
                // Async tracking logic
            });
        }
    }
    
  • Conditional Execution: Use closures to conditionally add tasks:

    if ($shouldProcessAsync) {
        $this->asyncListener->add(fn() => $this->processData());
    }
    
  • Error Handling: Wrap async tasks in try-catch:

    $this->asyncListener->add(function () {
        try {
            // Risky logic
        } catch (\Throwable $e) {
            \Log::error('Async task failed', ['error' => $e]);
        }
    });
    

Gotchas and Tips

Common Pitfalls

  1. Response Timing:

    • Async tasks only run after the response is sent. Avoid adding critical logic (e.g., auth checks) here.
    • Debug Tip: Use Symfony Profiler to verify async tasks execute post-response.
  2. Closure Scope:

    • Closures capture the current scope. Avoid referencing request-specific data (e.g., $request object) unless serialized properly.
    • Fix: Pass only serializable data or use dependency injection.
  3. Memory Leaks:

    • Long-running closures may block the async worker. Keep tasks lightweight.
    • Tip: Offload heavy work to queues (e.g., Symfony Messenger) if tasks exceed ~100ms.
  4. Configuration Overrides:

    • Default async worker runs in the same process. Customize via async.yaml:
      async:
          worker_process: 'async-worker' # Custom process name
          max_tasks: 10                  # Limit concurrent tasks
      

Debugging Tips

  • Log Async Execution: Enable debug mode and check Symfony logs for async task output.
  • Profiler Integration: Use the AsyncBundle\Profiler\AsyncCollector to inspect async tasks in the Symfony Profiler.
  • Worker Process: Ensure the async worker process is alive. Restart it if tasks stop executing:
    php bin/console async:restart-worker
    

Extension Points

  1. Custom Workers: Extend the AsyncWorker class to add pre/post-task hooks:

    class CustomAsyncWorker extends AsyncWorker {
        protected function beforeExecute(callable $task): void {
            // Pre-task logic
        }
    }
    

    Register in config/services.yaml:

    services:
        Danilovl\AsyncBundle\AsyncWorker:
            class: App\CustomAsyncWorker
    
  2. Task Prioritization: Implement a priority queue by wrapping closures in a PriorityTask object and sorting them in the worker.

  3. Async Middleware: Create middleware to auto-add async tasks for specific routes:

    public function handle(Request $request, callable $next): Response {
        $response = $next($request);
        $this->asyncListener->add(function () use ($request) {
            // Route-specific async logic
        });
        return $response;
    }
    
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.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
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