feat(esp-sync): debounce successive sync requests #3657
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.
All Submissions:
Changes proposed in this Pull Request:
Implements debounce-like behavior for ESP sync requests.
Currently, ESP sync requests are fired to the connected ESP's API immediately. However, successive data events can trigger a rapid series of sync requests. Given a site using premium newsletters tied to memberships tied to subscriptions, the single act of renewing a reader subscription will result in the following events:
on-hold
status pending a successful paymentpaused
status, pending the subscription's reactivationactive
statusEach of these data events triggers its own ESP sync, but ultimately only the last one matters. However, we can't just skip the prior steps as payment could fail along the way, which means we would want to sync the reader's change in membership status as a result.
Instead of immediately firing sync requests, this PR will store contact data as user meta which is continuously updated with each sync request, then schedule a sync with the ESP's API ~2 minutes in the future. If other sync requests come in before the scheduled sync happens, the scheduled sync is cancelled, the contact data in user meta is updated again, and another sync is scheduled ~2 minutes in the future. Once 2 minutes elapse without another sync request, the contact data is once again updated according to the user's current status (but reconciled with data stored in user meta—this is necessary to persist data that may only be available one time, such as signup UTM parameters) and then synced to the ESP. This should ensure that if multiple sync requests get triggered in rapid succession, only one sync is actually fired to the ESP's API, and always with the most up-to-date contact data that we have.
This should also solve for race conditions that might happen if two sync requests are fired simultaneously, as the contact data will be refreshed again at the moment the sync is sent to the ESP.
The PR also supports passing a
$delay
value of0
to sync immediately, basically retaining the current non-debounced behavior. This is still used for sync requests triggered by an admin action (manual resync via the Users admin UI) or CLI script, as these bulk syncs should only result in one sync per user per action.How to test the changes in this Pull Request:
wp cron event list
, confirm that there are two non-recurring cron jobs with thenewspack_scheduled_esp_sync
hook scheduled ~2 minutes after each completed transaction, and that the sync to the ESP doesn't actually happen before the scheduled cron jobs occur.wp cron event run newspack_scheduled_esp_sync
to trigger them early, and confirm that both contacts are synced to the ESP.newspack_scheduled_esp_sync
cron job is scheduled for each.wp cron event run newspack_scheduled_esp_sync
to trigger them early, and confirm that each contact is synced to the ESP only once with up-to-date data.on-hold
status and pause the membership)[currently failing: needs a fix](EDIT: fixed by fix(esp-sync): get inactive subscriptions with failed or pending orders #3658) Wait ~2 minutes or runwp cron event run newspack_scheduled_esp_sync
to trigger the job early, and confirm that the contact is correctly synced with aNP_Membership Status
value ofon-hold
. Also confirm that the user is unsubscribed from any premium newsletter lists associated with the paused membership. (This tests that failed renewals still sync the non-active status correctly.)wp newspack esp sync
command).Other information: