feat: add self-healing sync queue for failed writes - #4349
Open
faisalahammad wants to merge 1 commit into
Open
Conversation
Adds a persistent journal of failed Elasticsearch/OpenSearch write
operations (index, delete, bulk index) and a WP-CLI command to replay
them when the search server is reachable again.
New files:
- FailedWrites.php - journal class with dbDelta table, record(), get_pending(),
delete_entries(), count_pending() methods
- TestFailedWrites.php - 13 tests covering all journal operations
Modified files:
- elasticpress.php - bump version to 5.4.0, instantiate FailedWrites
- Command.php - add replay-queue subcommand with --limit, --dry-run,
--skip-health-check flags
- Indexable.php - fire ep_after_delete_{slug} hook for delete capture
- Upgrades.php - add 5.4.0 upgrade routine creating the journal table
- uninstall.php - drop the journal table on uninstall
Fixes 10up#4226
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When Elasticsearch/OpenSearch is briefly unreachable, write operations (index, delete, bulk index) fail silently. The WordPress database and search index drift out of sync until the next full re-index. This adds a persistent journal of failed writes and a WP-CLI command to replay them once the search server is back.
Fixes #4226
Changes
New: FailedWrites.php
Journal class owning a
{prefix}ep_failed_writestable created viadbDelta. Captures failed index/delete operations with dedup by(indexable_slug, object_id). Methods:record(),get_pending(),delete_entries(),count_pending().elasticpress.php
Bump EP_VERSION to 5.4.0. Instantiate
FailedWrites::factory()on plugin load.Command.php
Add
replay-queuesubcommand with--limit,--dry-run,--skip-health-checkflags. Replays each journal entry by re-indexing or re-deleting, clears on success, records new error on failure.Before: No way to recover from transient failures without a full re-index.
After:
wp elasticpress replay-queuereplays captured failures.Why: Matches the reporter's request for a WP-CLI-based recovery mechanism and avoids the cost of a full re-index.
Indexable.php
Fire
ep_after_delete_{slug}action afterdelete_document()so delete failures are capturable. Index and bulk-index paths already had hooks.Upgrades.php
5.4.0 upgrade routine creates the journal table via
dbDeltaon first install and on upgrade.uninstall.php
Drop the
ep_failed_writestable on uninstall. Multisite: each site's table is dropped in the per-site loop.New: TestFailedWrites.php
13 tests (30 assertions): record inserts, dedup by slug+id, get_pending ordering, delete_entries, count_pending, delete/update failure capture, dry-run CLI, live replay CLI, multisite blog_id capture, table creation on upgrade.
Testing
Test 1: Journal captures failed writes
ep_hostto an unreachable hostwp db query "SELECT * FROM wp_ep_failed_writes"shows a rowTest 2: Replay restores sync
ep_hostwp elasticpress replay-queueshows success with progress barTest 3: Dry-run mode
wp elasticpress replay-queue --dry-runshows entries without executingTest 4: Unit tests
vendor/bin/phpunit --filter TestFailedWrites- OK (13 tests, 30 assertions)Test 5: Uninstall
wp plugin uninstall elasticpressdrops the journal table