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

Fixed race condition when updating member's last_seen_at timestamp #20389

Conversation

cmraible
Copy link
Contributor

@cmraible cmraible commented Jun 13, 2024

ref https://linear.app/tryghost/issue/ENG-1240/race-condition-when-updating-members-last-seen-at-timestamp

When members click a link in an email, Ghost updates the member's last_seen_at timestamp, but it should only update the timestamp if the member hasn't yet been seen in the current day (based on the publication's timezone).

Currently there is a race condition present where multiple simultaneous requests from the same member (if e.g. an email link checker is following all links in an email) can cause the last_seen_at timestamp to be updated multiple times in the same day for the same member. These additional queries add a significant load on Ghost and its database, which can contribute to the exhaustion of the connection pool and eventually requests may time out.

The primary motivation for this change is to avoid that race condition by adding a lock to the member row, checking if last_seen_at has already been updated in the current day, and only updating it if it hasn't.

Another beneficial side-effect of this change is that it avoids locking the labels and newsletters tables, which are locked when we update the last_seen_at timestamp in the members table currently. This should improve Ghost's ability to handle a large influx of requests to redirect endpoints (confirmed with load tests), which tend to happen immediately after a publisher sends an email.

@cmraible
Copy link
Contributor Author

So far, have managed to fix the race condition, but may have broken a few other things — cleaning things up and adding tests now.

@cmraible cmraible force-pushed the chris-eng-1240-race-condition-when-updating-members-last_seen_at-timestamp branch from 59fbbf6 to e76fc01 Compare June 17, 2024 22:28
ref https://linear.app/tryghost/issue/ENG-1240/race-condition-when-updating-members-last-seen-at-timestamp

When members click a link in an email, Ghost updates the member's `last_seen_at` timestamp, but it should only update the timestamp if the member hasn't been seen in the current day (based on the publication's timezone).

Currently there is a race condition present where multiple simultaneous requests from the same member (if e.g. an email link checker is following all links in an email) can cause the `last_seen_at` timestamp to be updated multiple times in the same day for the same member. These additional queries add a significant load on Ghost and its database, which can contribute to the exhaustion of the connection pool and eventually requests may time out.

The primary motivation for this change is to avoid that race condition by adding a lock to the member row, checking if `last_seen_at` has already been updated in the current day, and only updating it if it hasn't.

Another beneficial side-effect of this change is that it avoids locking the `labels` and `newsletters` tables, which are locked when we update the `last_seen_at` timestamp in the `members` table currently. This should improve Ghost's ability to handle a large influx of requests to redirect endpoints, which tend to happen immediately after a publisher sends an email.
@cmraible cmraible force-pushed the chris-eng-1240-race-condition-when-updating-members-last_seen_at-timestamp branch from a13e0bb to 614cc7d Compare June 19, 2024 02:18
@cmraible cmraible marked this pull request as ready for review June 19, 2024 02:18
@cmraible cmraible merged commit 5154e8d into TryGhost:main Jun 19, 2024
22 checks passed
cmraible added a commit that referenced this pull request Jun 19, 2024
#20389)

ref
https://linear.app/tryghost/issue/ENG-1240/race-condition-when-updating-members-last-seen-at-timestamp

When members click a link in an email, Ghost updates the member's
`last_seen_at` timestamp, but it should only update the timestamp if the
member hasn't yet been seen in the current day (based on the
publication's timezone).

Currently there is a race condition present where multiple simultaneous
requests from the same member (if e.g. an email link checker is
following all links in an email) can cause the `last_seen_at` timestamp
to be updated multiple times in the same day for the same member. These
additional queries add a significant load on Ghost and its database,
which can contribute to the exhaustion of the connection pool and
eventually requests may time out.

The primary motivation for this change is to avoid that race condition
by adding a lock to the member row, checking if `last_seen_at` has
already been updated in the current day, and only updating it if it
hasn't.

Another beneficial side-effect of this change is that it avoids locking
the `labels` and `newsletters` tables, which are locked when we update
the `last_seen_at` timestamp in the `members` table currently. This
should improve Ghost's ability to handle a large influx of requests to
redirect endpoints (confirmed with load tests), which tend to happen
immediately after a publisher sends an email.
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.

None yet

1 participant