queue->push($payload); } /** * Push a domain event (high priority for business logic) */ public function pushDomainEvent(object $event): void { $this->pushEvent( event: $event, priority: QueuePriority::high(), timeout: Duration::fromMinutes(1), retryStrategy: RetryStrategyHelper::forEvents() ); } /** * Push a system event (normal priority for system operations) */ public function pushSystemEvent(object $event): void { $this->pushEvent( event: $event, priority: QueuePriority::normal(), timeout: Duration::fromMinutes(3), retryStrategy: RetryStrategyHelper::forEvents() ); } /** * Push an integration event (low priority, high retry tolerance) */ public function pushIntegrationEvent(object $event): void { $this->pushEvent( event: $event, priority: QueuePriority::low(), timeout: Duration::fromMinutes(10), retryStrategy: RetryStrategyHelper::forWebhooks() ); } /** * Push a notification event (background processing) */ public function pushNotificationEvent(object $event): void { $this->pushEvent( event: $event, priority: QueuePriority::low(), timeout: Duration::fromMinutes(5), retryStrategy: RetryStrategyHelper::forEmails() ); } /** * Push a delayed event (scheduled for future processing) */ public function pushDelayedEvent(object $event, Duration $delay): void { $this->pushEvent( event: $event, delay: $delay, priority: QueuePriority::normal(), timeout: Duration::fromMinutes(2) ); } /** * Push a critical event (immediate processing, no retries) */ public function pushCriticalEvent(object $event): void { $this->pushEvent( event: $event, priority: QueuePriority::critical(), timeout: Duration::fromSeconds(30), retryStrategy: RetryStrategyHelper::none() ); } /** * Pop the next event from the queue * * @return object|null The next event object or null if queue is empty */ public function popEvent(): ?object { $payload = $this->queue->pop(); return $payload?->job; } /** * Peek at the next event without removing it * * @return object|null The next event object or null if queue is empty */ public function peekEvent(): ?object { $payload = $this->queue->peek(); return $payload?->job; } /** * Pop the next event with its metadata * * @return JobPayload|null The complete job payload or null if queue is empty */ public function popEventWithMetadata(): ?JobPayload { return $this->queue->pop(); } /** * Get number of pending events */ public function size(): int { return $this->queue->size(); } /** * Check if queue is empty */ public function isEmpty(): bool { return $this->size() === 0; } /** * Clear all events from queue * * @return int Number of events removed */ public function clear(): int { return $this->queue->clear(); } /** * Get event queue statistics */ public function getStats(): array { $stats = $this->queue->getStats(); return [ 'type' => 'event', 'size' => $this->size(), 'is_empty' => $this->isEmpty(), ...$stats, ]; } /** * Batch push multiple events * * @param array $events Array of event objects * @param QueuePriority|null $priority Priority for all events */ public function pushBatch(array $events, ?QueuePriority $priority = null): void { foreach ($events as $event) { $this->pushEvent($event, $priority); } } /** * Push events with different priorities based on event type * * @param array $events Array of event objects */ public function pushSmartBatch(array $events): void { foreach ($events as $event) { $this->pushEventByType($event); } } /** * Pop multiple events in batch * * @param int $count Maximum number of events to pop * @return array Array of event objects */ public function popBatch(int $count): array { $events = []; for ($i = 0; $i < $count; $i++) { $event = $this->popEvent(); if ($event === null) { break; } $events[] = $event; } return $events; } /** * Filter events by type/class * * @param string $eventClass The event class to filter by * @return array Events of the specified type */ public function getEventsByType(string $eventClass): array { $events = []; $tempEvents = []; // Pop all events temporarily while (! $this->isEmpty()) { $payload = $this->popEventWithMetadata(); if ($payload === null) { break; } if ($payload->job instanceof $eventClass) { $events[] = $payload->job; } else { $tempEvents[] = $payload; } } // Push back non-matching events foreach ($tempEvents as $payload) { $this->queue->push($payload); } return $events; } /** * Get events count by priority * * @return array Priority name => count mapping */ public function getEventCountByPriority(): array { $stats = $this->getStats(); return $stats['priority_breakdown'] ?? []; } /** * Push event with automatic priority based on event type */ private function pushEventByType(object $event): void { $className = get_class($event); // Automatic priority assignment based on event name patterns if (str_contains($className, 'Domain') || str_contains($className, 'Business')) { $this->pushDomainEvent($event); } elseif (str_contains($className, 'System') || str_contains($className, 'Application')) { $this->pushSystemEvent($event); } elseif (str_contains($className, 'Integration') || str_contains($className, 'External')) { $this->pushIntegrationEvent($event); } elseif (str_contains($className, 'Notification') || str_contains($className, 'Email')) { $this->pushNotificationEvent($event); } elseif (str_contains($className, 'Critical') || str_contains($className, 'Alert')) { $this->pushCriticalEvent($event); } else { // Default to system event $this->pushSystemEvent($event); } } }