Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(esp-sync): debounce successive sync requests #3657

Draft
wants to merge 1 commit into
base: trunk
Choose a base branch
from

Conversation

dkoo
Copy link
Contributor

@dkoo dkoo commented Jan 7, 2025

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:

  1. The reader's subscription gets put into on-hold status pending a successful payment
  2. The reader's membership gets put into paused status, pending the subscription's reactivation
  3. The reader's subscription(s) to the premium newsletter list(s) tied to the membership gets revoked
  4. After payment is complete, the subscription gets put back into active status
  5. The membership gets reactivated
  6. The premium newsletter subscription(s) gets reinstated

Each 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 of 0 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:

  1. Check out this branch.
  2. Purchase new subscriptions (preferably ones tied to memberships and premium newsletters) as two separate readers.
  3. Using WP CLI's wp cron event list, confirm that there are two non-recurring cron jobs with the newspack_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.
  4. Wait until both jobs fire, or run wp cron event run newspack_scheduled_esp_sync to trigger them early, and confirm that both contacts are synced to the ESP.
  5. As an admin, manually renew both subscriptions within two minutes and confirm again that both renewals trigger a series of sync requests moving through the subscription/membership status changes, but that in the end, only one newspack_scheduled_esp_sync cron job is scheduled for each.
  6. Wait until both jobs fire, or run 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.
  7. As an admin, use the Order Actions menu to create a pending renewal order (which will put the subscription in on-hold status and pause the membership)
Screenshot 2025-01-07 at 4 36 32 PM
  1. [currently failing: needs a fix] (EDIT: fixed by fix(esp-sync): get inactive subscriptions with failed or pending orders #3658) Wait ~2 minutes or run wp cron event run newspack_scheduled_esp_sync to trigger the job early, and confirm that the contact is correctly synced with a NP_Membership Status value of on-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.)
  2. Smoke test manual resyncs via the admin Users UI and via WP CLI (wp newspack esp sync command).

Other information:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes, as applicable?
  • Have you successfully ran tests with your changes locally?

@dkoo dkoo self-assigned this Jan 7, 2025
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