Repository navigation
Conversation
…tion Scheduler and added db cleanup code
… asynchronous processing
…ement , improved sync UI
…g on history table
… in CI
Strauss 0.27.0 validates the GitHub OAuth token format, but the
GITHUB_TOKEN provided by GitHub Actions uses the ghs_* format
(contains underscores) which fails Strauss's regex validation.
Fix: run `composer install --no-scripts` to skip post-install-cmd,
then run `composer run prefix-namespaces` in a separate step with
`COMPOSER_AUTH: '{}'` to prevent Strauss from reading the invalid token.
Applies to both reusable-phpcs.yml and reusable-phpstan.yml.
Co-authored-by: Kallyan01 <48629100+Kallyan01@users.noreply.github.com>
…nd PHP compatibility - Add mock for /re-index/status fetch that fires on component mount - Update re-index modal test to use Close button and check dialog removal - Mock fetchHistory calls for modal open and reindex handler flows - Fix add_option deprecated empty string autoload parameter (use false) - Guard direct SQL query with prepare result type check - Update PHPStan types and ActionScheduler stub - Use COMPOSER_HOME isolation for strauss to avoid CI token validation failure - Upgrade strauss from 0.27.0 to 0.27.3 - Use overlayClassName on Modal with CSS :has() instead of wrapper div blur - Fix CSS formatting inconsistencies
…ent on SiteIndexableEntities component
7 tasks done
Collaborator
|
Superseded by #365 (@Kallyan01 if you're curious, I went with a simpler approach) |
Collaborator
Author
|
@justlevine, I think it would be beneficial to introduce a plan or design approval step before starting implementation of a new feature and raising a PR. This would help align everyone on the proposed approach early and reduce the chances of disagreements during code review and rework. Thoughts? |
Collaborator
|
@Kallyan01 👍
|
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.
What
Moves Algolia indexing off the request thread and onto Action Scheduler. A re-index now runs as a parent job that queues one batch job per 100 posts, and a post save queues a sync job instead of writing to Algolia inline. Jobs are stored in a new
wp_onesearch_index_jobstable. The admin gets a live progress modal, cancel, retry and a paginated job history, on the governing site and on its brand sites.Why
POST /re-indexused to index the whole site inside the REST request. On a governing site, that request also waited over HTTP for each brand site's re-index. On larger sites the request times out partway through and leaves a half-built index. There was no way to see what finished, retry what failed or stop the run. Post saves had the same problem on a smaller scale: every publish or update waited for an Algolia write before the editor got its response.Related Issue(s):
How
Job stack on each site
flowchart TB Start(["POST /re-index"]) Save(["Post saved"]) Ctl(["/jobs/{id} requests"]) SC["Search_Controller<br/>token check · re-index lock"] PT["Indexable post types<br/>governing: own settings<br/>brand: GET /brand-config, cached"] RJ["Reindex_Job<br/>parent"] W["Watcher"] JRC["Job_REST_Controller"] JS["Job_Scheduler"] DB[("wp_onesearch_index_jobs<br/>+ transient cache")] AS[["Action Scheduler"]] SJ["Sync_Job × N<br/>100 posts each"] IDX["Indexer"] ALG[("Algolia index")] Start --> SC SC --> PT SC -->|"governing: runs it now<br/>brand: schedules it on AS"| RJ RJ -->|"1 · clear site records"| IDX RJ -->|"2 · store + enqueue batches"| JS Save --> W W -->|"queue Sync_Job"| JS Ctl --> JRC JRC -->|"status · retry · cancel"| JS JS <--> DB JS --> AS AS --> SJ SJ -->|"save / delete posts"| IDX SJ -.->|"notify_parent()"| JS IDX -->|"batched writes"| ALGRe-index: starting a run
sequenceDiagram autonumber actor Admin participant UI as Admin UI participant G as Governing site participant GQ as Governing jobs participant B as Brand site participant BQ as Brand jobs participant A as Algolia Admin->>UI: Click Re-index UI->>G: POST /re-index G->>G: Take re-index lock, 409 if a run is live loop Each connected brand site, one at a time G->>B: POST /re-index with X-OneSearch-Token, 45s timeout B->>B: Check token, take the brand's re-index lock opt Brand config not cached B->>G: GET /brand-config with token G-->>B: indexable_entities, algolia_credentials end B->>B: Count batches for the brand's post types B->>BQ: Store Reindex_Job, schedule it, start the runner B->>B: Save re-index state, release lock B-->>G: job_id, batch_count end Note over G,B: A brand that errors or returns no job_id goes into errors and is left out of the run G->>A: Clear governing records G->>GQ: Store one Sync_Job per 100 posts and enqueue them G->>G: Store sites and total_batches on the parent, save re-index state, release lock G-->>UI: job_id, jobs[] for every siteFeature list
AI Disclosure
Architected the overall job workflow, implemented key components, and use Claude 5.5 for migration, testing, feedback, and feature enhancements.
Added API
All routes are under
/wp-json/onesearch/v1.Permission key
manage_options, or anX-OneSearch-Tokenheader that matches this site's API key. The governing site uses the token to read its brand sites' jobs.check_api_permissions(), the same check the existing OneSearch endpoints use.manage_optionsonly.New endpoints
GET/re-index/statusactive: falseonce every job is finished or stale.GET/jobs/historypage(default 1),per_page(default 5, max 100). Returnsjobs,total,page,per_page,total_pages.GET/jobs/{id}GET/jobs/{id}/childrenPOST/jobs/{id}/retryDELETE/jobs/{id}GET/jobs/remote-statusGET /jobs/{id}on a brand site from the governing site. Query:site_url,job_id.POST/jobs/remote-retryPOST /jobs/{id}/retryon a brand site from the governing site. Body:site_url,job_id.POST/jobs/remote-cancelDELETE /jobs/{id}on a brand site from the governing site. Returns success even if the brand site is unreachable. Body:site_url,job_id.Changed endpoints
POST /re-indexnow schedules jobs and returns right away:{ "success": true, "message": "Re-indexing scheduled successfully.", "errors": [], "job_id": "3f2c…", "batch_count": 12, "jobs": [ { "site_name": "Governing Site", "site_url": "https://gov.example", "job_id": "3f2c…", "batch_count": 12 }, { "site_name": "Brand A", "site_url": "https://brand-a.example", "job_id": "9a1e…", "batch_count": 8 } ] }409 onesearch_reindex_activewhile another run is live.rest_forbidden).messagenow contains each failing site's own error messages instead of the generic "Re-indexing was unsuccessful".POST /algolia-credentials: on a governing site, rejects requests that carry a brand token (rest_forbidden).Testing Instructions
OneSearch Async Re-indexing – Testing Instructions
Prerequisites
composer install.npm run build.Phase 1: Basic Functionality
1. Database Table Creation
wp db query "SHOW TABLES LIKE '%onesearch_index_jobs'"wp_onesearch_index_jobstable exists.2. Re-indexing
3. Progress Persistence
4. Post Sync
onesearch_watchergroup.onesearch_execute_jobaction completes.Phase 2: Job Management
5. Concurrent Re-index Prevention
409and the message "A re-index is already in progress."6. Job Cancellation
onesearch_execute_jobactions remaining for that run.7. Job History
Phase 3: Failure Recovery and Retries
8. Retry – Full Restart
9. Retry – Failed Batches Only
Final acceptance criteria: Re-indexing, post synchronization, governing-to-brand orchestration, cancellation, retries, history, and access control work correctly without leaving orphaned jobs or pending scheduled actions.
Screenshots
Checklist