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

Pendingactions Bundle Laravel Package

clavicula-nox/pendingactions-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require clavicula-nox/pendingactions-bundle
    

    Add to config/bundles.php:

    return [
        // ...
        ClaviculaNox\PendingActionsBundle\PendingActionsBundle::class => ['all' => true],
    ];
    
  2. Configure Database: Run migrations (check docs/installation.md for schema details) to create the pending_action table.

  3. First Use Case: Create a command to trigger a pending action:

    use ClaviculaNox\PendingActionsBundle\Entity\PendingAction;
    use ClaviculaNox\PendingActionsBundle\Manager\PendingActionManager;
    
    class MyCommand extends Command
    {
        private $pendingActionManager;
    
        public function __construct(PendingActionManager $pendingActionManager)
        {
            $this->pendingActionManager = $pendingActionManager;
        }
    
        protected function execute(InputInterface $input, OutputInterface $output)
        {
            $pendingAction = new PendingAction();
            $pendingAction->setAction('App\Action\MyHeavyTaskAction');
            $pendingAction->setPayload(['param1' => 'value1']);
            $pendingAction->setScheduledAt(new \DateTime('+1 hour')); // Schedule for 1 hour later
    
            $this->pendingActionManager->create($pendingAction);
        }
    }
    
  4. Run the Consumer: Add a cron job or Symfony command to process pending actions:

    php bin/console clavicula-nox:pending-actions:consume
    

Implementation Patterns

Core Workflow

  1. Enqueue Actions: Use PendingActionManager to create actions with:

    • Action: Fully qualified class name of a callable (e.g., App\Action\ProcessOrderAction).
    • Payload: Serialized data (e.g., ['order_id' => 123]).
    • Schedule: scheduledAt (for delayed execution) or immediate (for instant processing).
    $pendingAction = new PendingAction();
    $pendingAction->setAction('App\Action\SendEmailAction');
    $pendingAction->setPayload(['user_id' => 42, 'template' => 'welcome']);
    $pendingAction->setScheduledAt(new \DateTime('+5 minutes')); // Delayed by 5 mins
    $manager->create($pendingAction);
    
  2. Process Actions: Implement a handler (e.g., ServiceHandler) to execute actions. Default handlers:

    • Service Handler: Instantiates and calls a service method.
      # config/packages/clavicula_nox_pending_actions.yaml
      clavicula_nox_pending_actions:
          handlers:
              service:
                  enabled: true
                  namespace: 'App\Action' # Auto-discover actions in this namespace
      
    • Custom handlers can be registered via dependency injection.
  3. Retry Logic: Configure retries for failed actions:

    clavicula_nox_pending_actions:
        retry:
            max_attempts: 3
            delay: 60 # seconds between retries
    
  4. Bulk Processing: Use the consume command with --limit to process actions in batches:

    php bin/console clavicula-nox:pending-actions:consume --limit=20
    

Integration Tips

  1. Event-Driven Triggers: Hook into Symfony events (e.g., kernel.request) to enqueue actions dynamically:

    $eventDispatcher->addListener('kernel.request', function (KernelEvent $event) {
        if ($event->getRequest()->isXmlHttpRequest()) {
            $pendingAction = new PendingAction();
            $pendingAction->setAction('App\Action\LogRequestAction');
            $pendingAction->setPayload(['request' => $event->getRequest()->query->all()]);
            $manager->create($pendingAction);
        }
    });
    
  2. Background Processing: Run the consumer in a separate process (e.g., using Supervisor) for high-throughput systems:

    [program:pending-actions]
    command=php bin/console clavicula-nox:pending-actions:consume --limit=50
    autostart=true
    autorestart=true
    
  3. Monitoring: Extend the PendingAction entity to track metadata (e.g., created_at, updated_at, status):

    // src/Entity/CustomPendingAction.php
    class CustomPendingAction extends PendingAction
    {
        #[ORM\Column(type: 'string', length: 50)]
        private $status = 'pending';
    
        #[ORM\Column(type: 'datetime')]
        private $createdAt;
    }
    
  4. Testing: Mock PendingActionManager in tests to verify actions are enqueued:

    $mockManager = $this->createMock(PendingActionManager::class);
    $mockManager->expects($this->once())
                ->method('create')
                ->with($this->isInstanceOf(PendingAction::class));
    
    $service = new MyService($mockManager);
    $service->triggerHeavyTask();
    

Gotchas and Tips

Pitfalls

  1. Serialization Issues:

    • Payloads must be serializable (avoid closures, resources, or non-serializable objects).
    • Use json_encode()/json_decode() for complex objects:
      $payload = json_encode(['data' => $complexObject->toArray()]);
      
  2. Handler Resolution:

    • If using ServiceHandler, ensure the action class is autowireable and its method is public static.
    • Example action:
      namespace App\Action;
      class SendEmailAction {
          public static function execute(array $payload, ManagerRegistry $registry) {
              // Logic here
          }
      }
      
  3. Timezone Handling:

    • scheduledAt uses the system timezone. Explicitly set timezone in code:
      $pendingAction->setScheduledAt((new \DateTime('+1 hour'))->setTimezone(new \DateTimeZone('UTC')));
      
  4. Database Locking:

    • The consumer uses SELECT ... FOR UPDATE to lock rows. Ensure your database supports this (e.g., PostgreSQL, MySQL with innodb_lock_wait_timeout configured).
  5. Circular Dependencies:

    • Avoid circular references in payloads (e.g., A references B, B references A). Use IDs or minimal data.

Debugging

  1. Log Failed Actions: Enable logging in config/packages/clavicula_nox_pending_actions.yaml:

    clavicula_nox_pending_actions:
        logging:
            enabled: true
            channel: 'pending_actions'
    

    Check logs for errors like:

    [2023-01-01 12:00:00] clavicula_nox.pending_actions.ERROR: Failed to execute action "App\Action\BrokenAction": Class not found []
    
  2. Manual Retries: Use the retry command to reprocess failed actions:

    php bin/console clavicula-nox:pending-actions:retry --id=123
    
  3. Query Performance: Add indexes to the pending_action table for large queues:

    CREATE INDEX idx_pending_action_scheduled_at ON pending_action(scheduled_at);
    CREATE INDEX idx_pending_action_status ON pending_action(status);
    

Extension Points

  1. Custom Handlers: Create a custom handler to extend functionality (e.g., HTTP callbacks):

    namespace App\PendingAction\Handler;
    
    use ClaviculaNox\PendingActionsBundle\Handler\HandlerInterface;
    
    class HttpHandler implements HandlerInterface
    {
        public function handle(PendingAction $action)
        {
            $client = new \GuzzleHttp\Client();
            $client->post('https://api.example.com/webhook', [
                'json' => $action->getPayload(),
            ]);
        }
    }
    

    Register it in services.yaml:

    services:
        App\PendingAction\Handler\HttpHandler:
            tags:
                - { name: clavicula_nox_pending_actions.handler, alias: 'http' }
    
  2. State Machine: Extend the state column to support custom workflows (e.g., pendingprocessingcompletedarchived):

    // src/Entity/CustomPendingAction.php
    const STATE_PENDING = 'pending';
    const STATE_PROCESSING = 'processing';
    const STATE_COMPLETED = 'completed';
    const STATE_ARCHIVED = 'archived';
    
  3. Priority Queues: Add a priority column to the pending_action table and sort queries accordingly:

    $qb->orderBy('p.priority', '
    
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.
nasirkhan/laravel-sharekit
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony