-
Notifications
You must be signed in to change notification settings - Fork 135
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
End of Year: sync Listening History #483
Conversation
… than 5 mins There are a lot of podcasts episodes with less than 30 minutes and we don't want to leave these users out
The only rule will look at is if there's any podcast from more than a year ago
@@ -20,7 +20,7 @@ class EndOfYearDataManager { | |||
let query = """ | |||
SELECT playedUpTo from \(DataManager.episodeTableName) | |||
WHERE | |||
playedUpTo > 1800 AND | |||
playedUpTo > 300 AND |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a user had listened to multiple episodes with less than 30 minutes they were not eligible, I changed that to just 5 minutes.
|
||
/// Helper that checks for podcast existence | ||
/// It caches database requests | ||
class PodcastExistHelper { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I created this to avoid calling the database over and over to check if an episode exists.
Hey @leandroalonso!
I don't think it would be a problem if we just call it once. The database query is pretty simple and the whole request doesn't execute any crazy calculations, so we should be fine if we just run it one time 👍 . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heya! This worked well in my testing. I left some comments, let me know what you think.
var dataToSync = Api_YearHistoryRequest() | ||
dataToSync.deviceTime = TimeFormatter.currentUTCTimeInMillis() | ||
dataToSync.version = apiVersion | ||
dataToSync.year = 2022 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about allowing this to be injected?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 9001df4
dispatchGroup.wait() | ||
|
||
// Sync episode status for the retrieved podcasts' episodes | ||
let uniqueUuidsToUpdate = Array(Set(podcastsToUpdate)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of converting the array -> set -> array. What do you think about just changing podcastsToUpdate to a Set?
var podcastsToUpdate: Set<String> = []
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in fecb93b
func markAsExistent(uuid: String) { | ||
checkedUuidsThatExist.append(uuid) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't seem to be used, should we remove it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 194ddec
|
||
/// Helper that checks for podcast existence | ||
/// It caches database requests | ||
class PodcastExistHelper { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit:
class PodcastExistHelper { | |
class PodcastExistsHelper { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 21f03cb
do { | ||
let data = try dataToSync.serializedData() | ||
let (response, httpStatus) = postToServer(url: url, token: token, data: data) | ||
if let response = response, httpStatus == ServerConstants.HttpConstants.ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit:
if let response = response, httpStatus == ServerConstants.HttpConstants.ok { | |
if let response, httpStatus == ServerConstants.HttpConstants.ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in fdd751b
If we identify the user doesn't have the entire 2022 listening history, we sync this with the server adding the missing episodes.
This is a case that might happen for a very active user that switched devices during this year — given we only sync the latest 100 items.
How do we identify if a user needs a sync?
We look at their listening history. If they have an episode from last year, we assume that their 2022 listening history is complete.A much more bulletproof strategy would be to call the endpoint to check the number of items for the user, and sync if needed, just once. But I'm not sure what would be the impact of such a call on the backend (@Ferdev curious to hear your thoughts about it).We request the number of items the server has. If the returned number is smaller than what we have locally, we sync the necessary items.
To test
You'll need an account with more than 100 items. Please ping me and I can provide one.
endOfYear
flag inFeatureFlag.swift
EndOfYearStoriesBuilder.swift
line39
Checklist
CHANGELOG.md
if necessary.