Skip to content

Make index dispatches failure-safe (and confirm async marker interface)#158

Open
loevgaard wants to merge 1 commit into
issue-112-incremental-default-filtersfrom
issue-124-failure-safe-async
Open

Make index dispatches failure-safe (and confirm async marker interface)#158
loevgaard wants to merge 1 commit into
issue-112-incremental-default-filtersfrom
issue-124-failure-safe-async

Conversation

@loevgaard

Copy link
Copy Markdown
Member

What

Out of the box every save of an indexable entity dispatches on the plugin's command bus, and since no transport routing is configured, the handler runs synchronously inside the Doctrine flush. If Meilisearch was slow or down, saving/deleting a product failed — a search-index hiccup broke catalog management.

Two parts:

  1. Resilience for the sync default. EntityListener now wraps every dispatch in try/catch and logs the failure at error (dedicated setono_sylius_meilisearch Monolog channel). A failed index update — or a transport outage on an async setup — can never break the entity save it reacts to.
  2. First-class async support. All plugin command messages already share the CommandInterface marker (directly or via EntityAwareCommand), so a single framework.messenger.routing entry can route everything to an async transport. The recommended routing snippet is documented in the operational-model docs issue ([Docs]: Document the operational model - async indexing, settings sync, production checklist #140).

Testing

EntityListenerTest::it_swallows_and_logs_a_failing_dispatch_so_the_entity_save_still_succeeds: with the command bus throwing, postPersist does not throw and an error is logged.

Closes #124


Stacked on #157 (#112).

@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.50000% with 1 line in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (issue-112-incremental-default-filters@be49d96). Learn more about missing BASE report.

Files with missing lines Patch % Lines
src/EventListener/Doctrine/EntityListener.php 87.50% 1 Missing ⚠️
Additional details and impacted files
@@                           Coverage Diff                            @@
##             issue-112-incremental-default-filters     #158   +/-   ##
========================================================================
  Coverage                                         ?   45.91%           
  Complexity                                       ?      749           
========================================================================
  Files                                            ?      133           
  Lines                                            ?     2450           
  Branches                                         ?        0           
========================================================================
  Hits                                             ?     1125           
  Misses                                           ?     1325           
  Partials                                         ?        0           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@loevgaard loevgaard force-pushed the issue-112-incremental-default-filters branch from cc64906 to df8d23f Compare July 10, 2026 17:16
@loevgaard loevgaard force-pushed the issue-124-failure-safe-async branch 2 times, most recently from ae8d80e to 74ad191 Compare July 10, 2026 17:20
@loevgaard loevgaard force-pushed the issue-112-incremental-default-filters branch from df8d23f to 6952c4f Compare July 10, 2026 17:20
Every save of an indexable entity dispatches on the plugin's command bus,
which (with no transport routing) runs synchronously inside the Doctrine
flush. If Meilisearch was slow or down, saving/deleting a product failed.

EntityListener now wraps every dispatch in try/catch and logs the error at
error level (dedicated setono_sylius_meilisearch monolog channel), so a
search-index hiccup — or a transport outage on an async setup — can never
break catalog management.

All plugin command messages already share the CommandInterface marker, so a
single framework.messenger.routing entry can route everything to an async
transport (documented separately in the operational-model docs).

Closes #124
@loevgaard loevgaard force-pushed the issue-124-failure-safe-async branch from 74ad191 to dfea6c9 Compare July 10, 2026 18:11
@loevgaard loevgaard force-pushed the issue-112-incremental-default-filters branch from 6952c4f to be49d96 Compare July 10, 2026 18:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant