-
Notifications
You must be signed in to change notification settings - Fork 114
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
🏗️🗃️ UnifiedDataLoader rewrite #1064
🏗️🗃️ UnifiedDataLoader rewrite #1064
Conversation
The 'Chats' and 'ReferHelper' services, alongside their derivative services, have not been used for quite some time. These were removed in preparation for the UnifiedDataLoader-rewrite.
Just a quick observation about the behavior or
Results in the output:
Should this always be empty? I've tried this on a few different emulators, timelines, and surveys: all of which had the same result. If this isn't intentional, I can look into it further - regardless, I'll be committing and pushing my rewrite soon! |
- Moved UnifiedDataLoader to a separate typescript file. - The method is no longer an angular service, and instead exports two 'getUnified' methods. - Updated other files that rely on this service. - Tested getUnifiedMessagesForoInterval, as used in enketoHelper.
From the manual tests I've done, the rewrite seems to be performing well! I did have two more questions:
Edit: I may be wrong, but I believe these are called during the initial loading and refresh processes! I've also gone ahead and rewritten getUnified, in 36cfff6 |
As discussed in PR #1052, switching the branches cleans the git logs to only contain my edits - I also updated the title, since I accidentally used a duplicate in icons : ) |
- Generalized getUnified functions into one method that takes a higher order function as input, and uses that to fetch required data. - Updated calls to the getUnified functions - Added an interface for the combineWithDedup method, because it requires objects with the 'metadata.writets' property to run - Updated other unifiedDataLoader functions so the parameters were appropriately typed
6988d17
to
36cfff6
Compare
Quick Update: Now that the My general approach has been to recursively build up the promises. For example, if we had an array of promises I'm pretty sure I'm making some jumps in my logic and missing something obvious - I'll spend some more time on the recursive approach, and switch gears if that doesn't go anywhere. |
- Updated combinePromise to now take a list of one or more promises as input, and recursively combine them to a single promise. - Added parameter explanations to each function - Cleaned up debuging console.log statements
- While the types themselves may be subject to change, the goal is to set up a good foundation for strict typing in the future! As such, I added some to a basic version of Jiji's diaryTypes (see PR e-mission#1061), and will be updating those regularly.
Many thanks to Jiji for doing the heavy lifting on this one in PR 1061! - Fixed indents - Switched ServerData from an interface to a Generic Type. After doing some further reading, the [TS Docs](https://www.typescriptlang.org/docs/handbook/2/objects.html#interfaces-vs-intersections) seem to suggest that this is a better way of handling container-style types. - Added basic ServerReponse type - this is often how data is wrapped when returned from functions like `getRawData()`
- Minor changes to unifiedDataLoader: adjusted logInfo, exports - Wrote test cases for combinedPromises
- Updated types to match PR e-mission#1073 - Part of the motivaiton for this is that `/dairy/services.js` also relies on unifiedDataLoader; if this is written using those types, then that rewrite can build off of this rewrite without any additional merge conflicts down the road.
Good thought! I vote for moving them into a new services/ directory. I think that the directories are within |
What is the key that the
If the key is a trip or place confirm or an addition, it may just be that your data has not been pushed to the server. Pick a stage token that is related to time use (I think I have one in the wiki) and test; you should see some results. Please report the results of this testing before I review further. |
Initial loading of the label screen, yes. |
At the time of writing, this does not pass the 'prettier' check because of |
* @param combiner a function that takes two arrays and joins them | ||
* @returns A promise which evaluates to a combined list of values or errors | ||
*/ | ||
export const combinedPromises = function ( |
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 was unsure why we have this big function just to join a list of promises, when Promise.all
already serves that purpose. I read back in the commit history and saw this approach was taken because Promise.all
fails if any one of the promises fails 34c5658 -- and we want local retrieval to work even when network is unavailable. That makes sense.
But now in 2023, I think we could use Promise.allSettled
(which probably was not supported by major browsers in 2017) and greatly simplify this.
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.
We would still need to dedup -- I think after the Promise.allSettled
call we would just merge with dedup
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 don't think it's necessary to do this before merging this PR, but it might be good to keep around as a 'future 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.
I didn't know Promise.allSettled
was an option, cool! I'll spend a bit of time seeing if I can get that to work : )
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.
Alas, this is still a pretty large function. I think it can be maybe be simplified without using a for loop, so unresolving this for a future cleanup while still merging.
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 thinking something like map((result) => result.status != 'fulfilled').reduce((a, b) => a && b);
Co-authored-by: Jack Greenlee <[email protected]>
- combinedPromises now uses `Promise.allSettled()` - rewrote tests to reflect change
* @param list An array of values from a BEMUserCache promise | ||
* @returns an array with duplicate values removed | ||
*/ | ||
export const removeDup = function (list: Array<ServerData<any>>) { |
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.
Note to self: we do the same deduplication here as we do in https://github.com/e-mission/e-mission-phone/pull/1086/files#diff-00cfb43594908885f4c2e9121a2224b2c080d9b96bff2e09ec6d4f8d8c6b0645R102-R104
Once both are merged it would be nice to use a common function in both places
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.
Leaving this open as a future cleanup
Co-authored-by: Jack Greenlee <[email protected]>
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.
LGTM
@the-bay-kay this now has merge conflicts again. I am going to try to resolve them to avoid an infinite cycle of changes. |
Ah, it failed because of prettier and I can't see anything obviously wrong with the file that it is flagging... |
I would fix it tonight if I could, but I don't have write access to this one |
~~If you'd like, I can fetch the current code, pull from |
@the-bay-kay as you can see, there is a failing test and it is not |
Fixed! I missed a couple imports in the merge, all tests are passing now. |
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 touches 46 files, so I am merging it now. But I expect that this will be cleaned up in your next PR.
@@ -72,7 +72,7 @@ const MetricsTab = () => { | |||
setAggMetrics(metrics as MetricsData); | |||
} | |||
} catch (e) { | |||
displayError(e, t('errors.while-loading-metrics')); | |||
logWarn(e + t('errors.while-loading-metrics')); // replace with displayErr |
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.
Flagging this as hack that we need to revert during cleanup
* @param list An array of values from a BEMUserCache promise | ||
* @returns an array with duplicate values removed | ||
*/ | ||
export const removeDup = function (list: Array<ServerData<any>>) { |
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.
Leaving this open as a future cleanup
const tripProps = points2TripProps(filteredLocationList); | ||
|
||
return { | ||
...tripProps, |
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: I thought that prettier would ensure that we wouldn't have this extraneous whitespace.
Is this related to the fact that prettier changes the function to one line and so the indentation changes.
function (
$http,
$ionicLoading,
$ionicPlatform,
$window,
$rootScope,
UnifiedDataLoader,
Logger,
$injector,
) {
------
function ($http, $ionicLoading, $ionicPlatform, $window, $rootScope, Logger, $injector) {
* @param combiner a function that takes two arrays and joins them | ||
* @returns A promise which evaluates to a combined list of values or errors | ||
*/ | ||
export const combinedPromises = function ( |
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.
Alas, this is still a pretty large function. I think it can be maybe be simplified without using a for loop, so unresolving this for a future cleanup while still merging.
* @param combiner a function that takes two arrays and joins them | ||
* @returns A promise which evaluates to a combined list of values or errors | ||
*/ | ||
export const combinedPromises = function ( |
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 thinking something like map((result) => result.status != 'fulfilled').reduce((a, b) => a && b);
write_local_dt: LocalDt; | ||
}; | ||
|
||
export type LocalDt = { |
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.
aren't these also defined elsewhere? I seem to remember merging the inputMatcher with similarly defined new types. Why is there a second copy of them?
|
||
export type TimeStampData = ServerData<RawTimelineData>; | ||
|
||
export type RawTimelineData = { |
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.
where is this used? The data we get from the server should be ServerData
with both metadata
and data
UnifiedDataLoader is the last remaining service in
/www/services.js
to be rewritten, as discussed in Issue 977. The remaining services in this file (Chats and ReferHelper) are no longer being used, so my plan is to remove these and then convertservices.js
intounifiedDataLoader.ts
.I did have an open question about the services.js rewrite - once all of the rewritten services are together, (commHelper, controlHelper, and unifiedData), should these be relocated into a directory other than
/www/js/
? I'm not sure whether these would be moved into a newservices/
directory, sorted into the current folders, or kept as they are. I figured it was worth thinking about how we wanted to organize these going forward, since the/www/js/
has expanded a bit!