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

Delayed Event Bundle Laravel Package

tjovaisas/delayed-event-bundle

Schedule Symfony events to dispatch later instead of immediately. This bundle queues delayed events and processes them when due, useful for reminders, time-based workflows, and background follow-up actions.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Bottom line: do not adopt this artifact. Harvest the ~150-line pattern and reimplement it. The package is a Symfony bundle, not a Laravel package, and it is effectively unmaintained.

Architecture fit

  • This is a Symfony bundle (Bundle subclass + DI extension + compiler pass) around a Doctrine ORM postFlush event subscriber. Its job is to queue domain events during a unit of work and dispatch them after the flush completes, so listeners never trigger a nested flush.
  • The prompt frames this as a "Laravel/PHP package." It is not. It targets Symfony's EventDispatcherInterface, Symfony's DI container, and Doctrine's EventManager. In Laravel, none of those are the native primitives: Laravel uses Illuminate\Contracts\Events\Dispatcher, its own service container, and (usually) Eloquent rather than Doctrine.
  • The only viable consumption path in a Laravel app is to bypass the bundle packaging entirely and register the subscriber directly on Doctrine's EventManager from a service provider. At that point you are using maybe 20% of the package and inheriting 100% of the dependency constraints.

Integration feasibility: low

  • Composer-level blocker likely. A bundle last released 2022-02-05 will typically constrain symfony/* to ^3.4|^4.4|^5.x and PHP to 7.x/8.0. Laravel 10/11 pull Symfony 6/7 components. Expect a hard composer update conflict; resolving it means a fork.
  • Trust signals are poor and worth flagging to procurement/security:
    • 1 star, 0 dependents, no release in ~3 years, single maintainer.
    • Package name (tjovaisas/delayed-event-bundle) does not match the referenced repo (tomas7777/lib-delayed-event-bundle) — classic republished-fork or rename pattern; provenance needs verification before any code review investment.
    • No evidence of CI, static analysis, security policy, or a changelog.
  • The functionality is not risky — deferred post-flush dispatch is a well-understood, small piece of logic. The risk is entirely in the artifact: unpatched transitive constraints, no security response, and no upstream to escalate to.

Key questions to answer before any further evaluation (spike, ~1 day)

  1. What are the exact composer.json constraints for PHP, doctrine/orm, and symfony/event-dispatcher / dependency-injection / http-kernel?
  2. How many source files / LOC is the actual dispatch logic? (Hypothesis: under 300, possibly under 150.)
  3. Does it guard against re-entrancy — a listener that flushes again — and does it dedupe identical events queued multiple times in one unit of work?
  4. What happens if a listener throws after the transaction has committed? Is there a retry, a log, or an outbox?
  5. Does it hold hard references to entities in the queue (identity-map retention / detached-entity errors after clear())?
  6. Is the deferred queue cleared on rollback, or does it leak events from a failed transaction into the next flush?

Integration Approach

Stack fit

  • Two niche choices stacked: Doctrine ORM inside Laravel is already non-idiomatic (laravel-doctrine/orm), and a Symfony bundle on top of that is a third layer. Most Laravel teams should solve this problem with Eloquent-native tools.
  • Laravel-native equivalents that cover the same requirement without this dependency:
    • DB::afterCommit(fn () => ...) for closure-based deferral.
    • Queued listeners with $afterCommit = true / ShouldQueueAfterCommit for job dispatch post-commit.
    • A small in-house Doctrine postFlush subscriber that drains a per-request queue into Laravel's dispatcher — this is the direct port of what the bundle does.
  • If the team is genuinely on Doctrine + Laravel, recommendation is: write the subscriber in-house (~1 dev-day plus tests), own it, and keep it under 200 LOC. The bundled abstraction is not buying enough to justify the fork.

Migration path (if a spike confirms the logic is small)

  1. Read the subscriber source; extract the queue + drain-on-postFlush algorithm. Ignore the Symfony bundle scaffolding.
  2. Reimplement as App\Doctrine\DeferredEventSubscriber registered via EventManager::addEventSubscriber() in a service provider, dispatching through Illuminate\Contracts\Events\Dispatcher.
  3. Bind a DeferredEventBuffer as a singleton scoped to the request/job; expose dispatchAfterCommit(object $event).
  4. Wire Doctrine\DBAL\Connection transaction state so the buffer is cleared on rollback, not just drained on flush.

Compatibility

  • Assume Symfony 6/7 and Doctrine ORM 3 are unsupported upstream. ORM 3 changed several lifecycle/event APIs; verify postFlush semantics and the EventArgs shape against the ORM version actually pinned.
  • PHP 8.2/8.3 deprecation surface (dynamic properties, DateTime internals) is unlikely to have been addressed since 2022.

Sequencing

  1. Spike (1 day): clone, read source, count LOC, confirm behaviour under nested flush, rollback, and listener exception.
  2. Decision gate: if logic ≤ 300 LOC → reimplement; if larger (unlikely) → escalate for a proper fork-and-own decision with a named maintainer.
  3. Build internal primitive with tests covering: single flush, nested flush, rollback discards queue, listener throws post-commit, batch flush of 10k entities.
  4. Pilot in one bounded context (e.g., order placement) where post-commit side-effects are already a known pain point.
  5. Roll out only after the pilot demonstrates no latency regression and no lost events on failure.

Operational Impact

Maintenance

  • Upstream is dormant. Any fork becomes an owned asset: budget ~2–5 engineer-days in year one (CI, PHPStan, PHP/Symfony/Doctrine upgrade churn) and ~2 days/year thereafter. A ~150-LOC in-house version carries roughly the same cost with none of the provenance questions.
  • Add CI (PHPUnit matrix over supported PHP + ORM versions), PHPStan level 8, and a short ADR documenting the flush-lifecycle contract.

Support

  • Single maintainer, GitHub issues only, no SLA, effectively no community. Do not plan on upstream fixes. The internal owner must be named in the service catalogue.

Scaling

  • postFlush dispatch is synchronous and runs inside the request/job lifecycle, after the DB commit but before the response. Long listener chains extend tail latency and hold the DB connection open past the transaction. Any listener doing I/O (mail, HTTP, cache bust) must be pushed to a queue.
  • Memory: the deferred queue accumulates for the duration of a unit of work. On batch jobs (imports, backfills) that flush thousands of entities, the queue grows proportionally, and if events hold entity references, the identity map stays bloated and entities go detached after clear(). Need a flush-and-drain policy per batch, not per job.
  • Ordering is only "after this flush" — not a global total order, and not coordinated with other postFlush subscribers registered by other packages.

Failure modes

  • Post-commit listener failure: data is committed, downstream effect (webhook, email, cache invalidation) is lost, and nothing retries. This is the classic dual-write problem; the real fix is an outbox table plus a relay, not an event buffer. If side-effects are business-critical, an outbox is the correct recommendation and this library does not provide one.
  • Lost-on-rollback ambiguity: if the queue isn't explicitly cleared on rollback, stale events can fire on the next successful flush — silent, hard to reproduce, and a data-integrity issue.
  • Re-entrant flush: a listener that touches the EntityManager and triggers a flush can recurse. Depends entirely on whether the library guards it; unverified.
  • Silent no-op: if the bundle/subscriber isn't registered (common when bypassing the bundle), events are queued and never dispatched — with no error. Registration must be covered by a smoke test asserting at least one known event fires.
  • Entity detachment: listeners receiving entity objects after clear() will hit EntityNotFoundException / detached-proxy errors.

Ramp-up

  • The logic is small; the concept is the cost. A mid-level developer needs 1–2 days to be productive and, critically, to understand why listeners must not flush or assume managed entities. Junior developers will treat dispatchAfterCommit as a general-purpose dispatch and reintroduce the bug the library exists to prevent. Mitigate with a code comment, an ADR, and a test that fails if a listener flushes.
  • Net: the package scores 0.005 for a reason — it is an abandoned Symfony bundle being evaluated for a Laravel stack. Adopt the pattern, not the dependency.
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.
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel