-
Notifications
You must be signed in to change notification settings - Fork 136
[WOOMOB-1722] - Properly clean the Bookings table for Today/Upcoming tabs' first page load #15022
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
Conversation
With this change when we fetch the initial page with the DateRange filter matching Today or Upcoming range the Bookings table will be cleared only from the bookings that are not in the initial page load.
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.
Pull request overview
This PR fixes a caching issue where deleted bookings weren't being removed from the local database when fetched from the server. The solution implements selective deletion of cached bookings for Today/Upcoming tabs on the first page load, ensuring stale data is properly cleaned up.
Key changes:
- Introduced
BookingsDateRangePresetsto provide canonical date range filters shared across app and data layers - Implemented conditional deletion logic in
BookingsStorethat clears cached bookings matching Today/Upcoming date ranges when fetching page 1 - Changed
BookingFiltersparameter from nullable to non-nullable withEMPTYas the default value
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
BookingsDateRangePresets.kt |
New utility object providing factory methods for today() and upcoming() date range presets with proper UTC handling |
BookingsStore.kt |
Added deletion logic for page 1 fetches with today/upcoming filters, plus isTodayOrUpcoming() helper method |
BookingsDao.kt |
Added deleteForSiteWithDateRangeFilter() query to selectively delete bookings matching date range and excluding specified IDs |
BookingListFiltersBuilder.kt |
Refactored to use shared BookingsDateRangePresets instead of inline date range construction |
BookingListHandler.kt |
Changed filters parameter type from nullable to non-nullable BookingFilters |
BookingsRepository.kt |
Updated filters parameter signature to non-nullable BookingFilters |
BookingsStoreTest.kt |
Added test cases for new deletion behavior scenarios and updated existing tests with Clock dependency |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
...rc/test/java/org/wordpress/android/fluxc/network/rest/wpcom/wc/bookings/BookingsStoreTest.kt
Show resolved
Hide resolved
...rc/test/java/org/wordpress/android/fluxc/network/rest/wpcom/wc/bookings/BookingsStoreTest.kt
Show resolved
Hide resolved
.../src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/bookings/BookingsStore.kt
Outdated
Show resolved
Hide resolved
...rc/test/java/org/wordpress/android/fluxc/network/rest/wpcom/wc/bookings/BookingsStoreTest.kt
Show resolved
Hide resolved
📲 You can test the changes from this Pull Request in WooCommerce-Wear Android by scanning the QR code below to install the corresponding build.
|
|
📲 You can test the changes from this Pull Request in WooCommerce Android by scanning the QR code below to install the corresponding build.
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## trunk #15022 +/- ##
============================================
+ Coverage 38.55% 38.57% +0.02%
- Complexity 10289 10297 +8
============================================
Files 2161 2162 +1
Lines 122614 122647 +33
Branches 16899 16904 +5
============================================
+ Hits 47271 47311 +40
+ Misses 70543 70527 -16
- Partials 4800 4809 +9 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
...otlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/bookings/BookingsDateRangePresets.kt
Outdated
Show resolved
Hide resolved
...otlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/bookings/BookingsDateRangePresets.kt
Outdated
Show resolved
Hide resolved
| // Clear existing bookings when fetching the first page. | ||
| // If filters are applied, only clear entries that match the applied filters, | ||
| // otherwise (no filters) clear all entries for the site. |
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.
The comment here is not entirely accurate. We say, If filters are applied, only clear entries that match the applied filters, but this is only true for date filters. The issue still exists for other filter types. For example, I filtered “No-show” bookings, trashed one, refreshed the list, and it was still visible.
If we want to address this for all cases, we’ll need to always delete cached entities when any filter is applied. Since it already works for the date filter, we could turn that into a more general solution. WDYT?
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.
Since it already works for the date filter, we could turn that into a more general solution. WDYT?
I initially did that, but then I thought that there was a reason why we added this check in the first place, so I decided to strictly add this logic for Today and Upcoming filter.
I'm open to changing that. I wonder if we had similar problems with Products or Orders, and how they were solved there?
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.
Hmm thinking about it, I'm not sure we need it. We can only apply other filters in the All tab. This tab, without filters applied, will delete or bookings for a selected site on the initial load. So the problems should be less visible and we won't be clearing the data that we would get on next page loads.
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.
True, the issue is less visible for the All tab, but the All filter is saved, and it's possible that the user prefers to always keep a certain filter enabled. In that case, it becomes the same situation as the Today and Upcoming tabs.
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'm open to changing that. I wonder if we had similar problems with Products or Orders, and how they were solved there?
I've just tested the Products tab, and the issue exists there as well.
| bookingsDao.deleteForSiteWithDateRangeFilter( | ||
| site.localId(), | ||
| filters.dateRange, | ||
| entities.map { it.id.value } | ||
| ) | ||
| bookingsDao.insertOrReplace(entities) |
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.
There is also an alternative way to handle removed bookings. We can compare the new entities with the cached bookings and detect the removed ones instead of removing all cached data. I know replaceAllForSite() is what we already use, but removing only trashed bookings seems like a better approach to me.
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.
Could you clarify? The current implementation only removes the local entities if they are not present in the response from the server. I'm not clearing all cached data here.
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.
cachedFilteredBookings = [A, B, C]
remoteFilteredBookings = [B, C, D] (A is removed)
// Current implementation
runNewDBTransaction {
remove(A, B, C)
insertOrReplace(B, C, D)
}
// My suggestion
runNewDBTransaction {
remove(A)
insertOrReplace(B, C, D)
}
In the current implementation, we remove the entire cachedFilteredBookings, right?
This is a minor suggestion and it won’t affect the behavior. It will make the DB work a smaller task, but we’ll still need to find the removed booking (A). Still, I think reducing the number of DB transactions is the better approach.
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.
In the current implementation, we remove the entire cachedFilteredBookings, right?
No. We pass the IDs of the fetched bookings and have this SQL query condition AND ((:idsSize = 0) OR id NOT IN (:ids)) to make sure we only delete the ones that are not in the list. It's exactly as in your suggestion.
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.
Oh, I missed that in the SQL. Then it’s okay. Thanks!
My last feedback: can we unify deleteForSiteWithDateRangeFilter() and insertOrReplace() into a single DB transaction? Having two separate transactions might trigger additional observations in the view models. I fixed a similar issue before here: #14800.
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.
In this case, this is not a problem, because we are only removing items that should be deleted. The other issue was created because we were deleting and then inserting the same items.
So in a scenario from #14800 the flickering would still occur, because the item will actually be deleted, no matter if it's wrapped in one transaction or not.
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 will wrap them in one transaction because it won't hurt us, but this wouldn't trigger the same issue mentioned above.
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.
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.
Yes, I noticed it currently doesn’t cause any issues, but it could still lead to a hard-to-diagnose problem in the future. Thanks for making the change. 👍🏻
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.
Good job noticing and addressing this issue. LGTM! This fixed the problem for the Today and Upcoming tabs. My two pieces of feedback were:
- Improving the stored cache deletion logic,
- Fixing the same issue for the All tab as well.
But these can be handled in a separate PR, no need to include them here. Approving! ✅
irfano
left a comment
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 requested changes again. Please check my last comment about unifying the db transactions.
WOOMOB-1722
Description
We had a small problem on Today/Upcoming tabs. If the booking displayed on one of those tabs would get deleted on the server, we wouldn't reflect that as the Booking would be cached locally and the app wouldn't delete it.
This PR fixes it by making sure that we clear the table from the bookings that were not received in the first page load for both Today and Upcoming tabs.
To do that, I extracted the creation of the Today/Upcoming
DateRangefilter so that I can create the same one inBookingStoreand check if that's the one used. After that, the app will delete all the bookings that match the givenDateRangefilter and if the Booking ID is not in the newly loaded list. This was done that way to be the least destructive to the Bookings table, so we only clear the entities that are indeed unnecessary (most likely).Test Steps
Images/gif
soft_clear.mp4
RELEASE-NOTES.txtif necessary. Use the "[Internal]" label for non-user-facing changes.