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

fix: streak issue - fetching last recover date with timezone #2452

Merged
merged 11 commits into from
Nov 20, 2024
Merged

Conversation

sshanzel
Copy link
Member

@sshanzel sshanzel commented Nov 16, 2024

This is a 2-part PR series about the issues surrounding the streak reset.

In this PR, this fixes an issue where the user has just restored their streak, but suddenly it was broken again. Referring to the issue mentioned here: dailydotdev/daily#1538 (comment)

The screenshot below tells the user did not read for two days straight, however, on the next screenshot, it can be seen that the user restored the streak that should allow him to continue the streak even when 2 days had passed.
Screenshot 2024-11-16 at 11 06 19 AM

For context, the user lost his streak and restored it as seen below. At 12:03 the email notification about the streak being reset was sent, and immediately after, the restoration happened.
Screenshot 2024-11-16 at 10 54 24 AM

We have a cron job that runs on an internal, and it takes consideration of the current streak and restores performed by the user. However, there was an issue with how we pulled the data about the date of recovering the streak.

In postgresql, setting a timezone on a timestamp column (without timezone information column), would either push or pull the time depending on the timezone value. In order to set correctly the timezone, we must convert the value itself to a timestamptz, and then set the correct timezone preferred by the user.

This explains the reset that happened, the query to pull all users that should get reset was inaccurate by converting inaccurate value from the recovery date.

Note: to show that it actually fixes the issue, I've introduced a test with the user's configuration. I will revert the fix temporarily to see if the test would fail.

This comment has been minimized.

This comment has been minimized.

This comment has been minimized.

This comment has been minimized.

Comment on lines +19 to +24
.select(`us.*`)
.addSelect(
`date_trunc('day', us."lastViewAt" at time zone COALESCE(u.timezone, 'utc'))::date`,
'lastViewAtTz',
)
.addSelect('u.timezone', 'timezone')
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just broke the 3 columns into their separate select statements to make the columns fetched more obvious.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the date_trunc and other things could become a function so we can reuse, since the same thing is used in some other parts outside of cron. Not needed for this PR though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Do you think of it as a javascript function that concatenates the query or something like a postgresql internal global function we would define?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

postgresql

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@rebelchris rebelchris left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trust this flow you tested, just sad we used timestamptz still, we manually convert anyhow so has no benefit now.

.addSelect('us.currentStreak', 'current')
.addSelect('u."weekStart"', 'weekStart')
.addSelect(
`(date_trunc('day', usa."lastRecoverAt" at time zone COALESCE(u.timezone, 'utc'))::date) - interval '1 day'`,
`(date_trunc('day', usa."lastRecoverAt"::timestamptz at time zone COALESCE(u.timezone, 'utc'))::date) - interval '1 day'`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't we discuss not doing the timestamptz columns for lots of reasons?
Not sure if we ended up not doing it, but they such a pain...

Copy link
Member Author

@sshanzel sshanzel Nov 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this column is not timestamptz. The problem occurs when you apply the time zone to a column similar to this (just timestamp).

Using at time zone in a non-timezone column messes up the values rather than adjusting to the right timezone. For us to use the at time zone statement, the column must be converted to timestamptz first (on query level only) even when the column is just a pure timestamp. Some nuances working with timezone in postgresql.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potentially we can extract date_trunc(...) and everything else in a function maybe so the query is a bit more readable. Does not need to happen in this PR just a note it is starting to be really hard to follow 😆

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, we are using AT TIME ZONE in digest and it correctly transforms there from what I see. But there we convert from NOW() so not sure if that is the difference.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess because NOW() includes the timezone offset
image

Copy link
Member Author

@sshanzel sshanzel Nov 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, using now works as intended since it includes the timezone information. Basically a timestamptz type is the value returned from the function.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potentially we can extract date_trunc(...) and everything else in a function maybe so the query is a bit more readable. Does not need to happen in this PR just a note it is starting to be really hard to follow 😆

Totally agree, especially have it in many places. Ticker created here: #2452 (comment)

@sshanzel
Copy link
Member Author

Trust this flow you tested, just sad we used timestamptz still, we manually convert anyhow so has no benefit now.

When working with AT TIME ZONE, we will have to convert the column first to get the right value. The entity itself is just a timestamp and if you add AT TIME ZONE with that type of column, postgresql would treat it as if the value is in that time zone already and not adjust the value then converts it to UTC, hence it gets pushed back.

This comment has been minimized.

This comment has been minimized.

This comment has been minimized.

Copy link

pulumi bot commented Nov 20, 2024

🍹 The Update (preview) for dailydotdev/api/prod was successful.

Resource Changes

    Name                                            Type                           Operation
-   vpc-native-api-migration-587473ef               kubernetes:batch/v1:Job        delete
~   vpc-native-clean-zombie-user-companies-cron     kubernetes:batch/v1:CronJob    update
~   vpc-native-hourly-notification-cron             kubernetes:batch/v1:CronJob    update
~   vpc-native-update-source-public-threshold-cron  kubernetes:batch/v1:CronJob    update
~   vpc-native-calculate-top-readers-cron           kubernetes:batch/v1:CronJob    update
~   vpc-native-update-views-cron                    kubernetes:batch/v1:CronJob    update
~   vpc-native-ws-deployment                        kubernetes:apps/v1:Deployment  update
~   vpc-native-update-trending-cron                 kubernetes:batch/v1:CronJob    update
+   vpc-native-api-migration-d9847687               kubernetes:batch/v1:Job        create
~   vpc-native-update-highlighted-views-cron        kubernetes:batch/v1:CronJob    update
~   vpc-native-personalized-digest-deployment       kubernetes:apps/v1:Deployment  update
~   vpc-native-bg-deployment                        kubernetes:apps/v1:Deployment  update
~   vpc-native-personalized-digest-cron             kubernetes:batch/v1:CronJob    update
~   vpc-native-sync-subscription-with-cio-cron      kubernetes:batch/v1:CronJob    update
~   vpc-native-update-tags-str-cron                 kubernetes:batch/v1:CronJob    update
~   vpc-native-private-deployment                   kubernetes:apps/v1:Deployment  update
~   vpc-native-clean-zombie-images-cron             kubernetes:batch/v1:CronJob    update
~   vpc-native-generate-search-invites-cron         kubernetes:batch/v1:CronJob    update
~   vpc-native-check-analytics-report-cron          kubernetes:batch/v1:CronJob    update
~   vpc-native-update-current-streak-cron           kubernetes:batch/v1:CronJob    update
~   vpc-native-update-tag-recommendations-cron      kubernetes:batch/v1:CronJob    update
~   vpc-native-daily-digest-cron                    kubernetes:batch/v1:CronJob    update
~   vpc-native-update-source-tag-view-cron          kubernetes:batch/v1:CronJob    update
~   vpc-native-temporal-deployment                  kubernetes:apps/v1:Deployment  update
~   vpc-native-deployment                           kubernetes:apps/v1:Deployment  update
~   vpc-native-clean-zombie-users-cron              kubernetes:batch/v1:CronJob    update
~   vpc-native-generic-referral-reminder-cron       kubernetes:batch/v1:CronJob    update

@sshanzel sshanzel merged commit 7741499 into main Nov 20, 2024
8 checks passed
@sshanzel sshanzel deleted the MI-620-tz branch November 20, 2024 07:29
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.

3 participants