alcalyn/flush-on-kernel-terminate-bundle
composer require alcalyn/flush-on-kernel-terminate:1.x
app/AppKernel.php:
new Alcalyn\FlushOnKernelTerminateBundle\AlcalynFlushOnKernelTerminateBundle(),
flush() calls (e.g., bulk operations, API batch processing) but need guarantees that pending changes persist before the request ends. No additional code changes are required—just rely on the bundle’s automatic listener.Deferred Flush Scenarios:
foreach ($entities as $entity) {
$entityManager->persist($entity);
// No flush() here
}
// Bundle flushes all pending changes after response.
/api/import).flush() is omitted for performance.Conditional Flushing:
$entityManager->flush() if needed (e.g., for critical data).@Transactional (Doctrine) to ensure atomicity where required.Event-Driven Extensions:
kernel.terminate in your own bundle:
$eventDispatcher->addListener(KernelEvents::TERMINATE, function () use ($em) {
if ($em->isOpen() && $em->getUnitOfWork()->hasScheduledEntityInsertions()) {
$em->flush();
}
});
Outdated Dependencies:
symfony/event-dispatcher) if migrating to newer Symfony versions.EntityManager State:
EntityManager is closed (e.g., after request end), the bundle silently fails. Ensure $em->isOpen() before flushing in custom logic.EntityManager#flush() to throw exceptions. Validate state pre-flush.Race Conditions:
$dispatcher->addListener(KernelEvents::TERMINATE, function () {
\Log::debug('FlushOnKernelTerminateBundle triggered flush.');
});
$uow = $em->getUnitOfWork();
\Log::debug('Pending inserts:', $uow->getScheduledEntityInsertions());
$dispatcher->removeListener(KernelEvents::TERMINATE, [$bundle, 'onKernelTerminate']);
$dispatcher->addListener(KernelEvents::TERMINATE, [$this, 'customFlushLogic']);
$em->getUnitOfWork()->getScheduledEntityInsertions()
->filter(fn ($entity) => !$entity instanceof SkippableEntity);
$dispatcher->addListener('flush.post', function () {
// Send webhook after flush.
});
Model::flush() or queue-based persistence.How can I help you explore Laravel packages today?