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

[HOLD for payment 2024-08-02] Moize - general purpose memoization tool #42200

Closed
kacper-mikolajczak opened this issue May 15, 2024 · 27 comments
Closed
Assignees
Labels
AutoAssignerAppLibraryReview Auto assign someone to review a new library being added to App Awaiting Payment Auto-added when associated PR is deployed to production Daily KSv2

Comments

@kacper-mikolajczak
Copy link
Contributor

kacper-mikolajczak commented May 15, 2024

In order to properly evaluate if a new library can be added to package.json, please fill out this request form. It will be automatically assigned someone from our review team that will go through and vet the library.

In order to add any new production dependency, it must be approved by the App Deployer team. They will evaluate the library and decide if it's something we want to move forward with or if other alternatives should be explored.

Note: This is only for production dependencies. While we don't want people to add packages to dev-dependencies willy-nilly, we recognize that there isn't as great of a need there to secure them.

Name of library: Moize

Details

  • Link to package: https://github.com/planttheidea/moize
  • Problem solved by using this package: App as of now, does not have a standardized way of handling memoization outside of React. It boils down to using custom-made solutions like Maps or serialization. This is a problem because engineers implementing and reviewing solutions for memoization outside of React have to sink time into writing and creating a custom solution that may not be consistent with other places in the codebase. This leads to inconsistency, overhead, and at times sub-optimal solutions.
  • Number of stars in GH: 880
  • Number of monthly downloads: 222,725 weekly!
  • Number of releases in the last year: 5
  • Level of activity in the repo: 17 contributors, 313 deployments, 3 issues, 6 PRs
  • Alternatives: List of alternatives and benchmarks
  • Are security concerns brought up and addressed in the library's repo? No
  • How many dependencies does this lib use that will be brought into our code? At most 1 (It uses 2 deps: fast-equals and micro-memoize but fast-equals is already used, not sure about micro-memoize)
  • What will the effect be on the bundle size of our code? Bundlephobia report of current moize version
Issue OwnerCurrent Issue Owner: @puneetlath
@kacper-mikolajczak kacper-mikolajczak added AutoAssignerAppLibraryReview Auto assign someone to review a new library being added to App Weekly KSv2 labels May 15, 2024
Copy link

melvin-bot bot commented May 15, 2024

Triggered auto assignment to @puneetlath (AutoAssignerAppLibraryReview), see https://stackoverflowteams.com/c/expensify/questions/17737 for more details.

Copy link

melvin-bot bot commented May 15, 2024

New Library Review

  • Are all the answers in the main description filled out properly and make sense?
  • Who maintains the library and how well is it maintained?
  • How viable are the alternatives?
  • Should we build it ourselves instead?

Once these questions are answered, start a thread in #engineering-chat, ping the @app_deployers group, and call for a vote to accept the new library. Once the vote is complete, update this issue with the outcome and procede accordingly. Here is a sample post:

Hey @app_deployers,

There is a request to add a new library to App that we need to consider. Please look at this GH and then vote :+1: or :-1: on accepting this new library or not.

GH_LINK

@roryabraham
Copy link
Contributor

After researching this, one of the things I like about moize is how the base API is extremely simple, but it's also configurable for just about any kind of memoization you might need.

@puneetlath
Copy link
Contributor

App as of now, does not have a standardized way of handling memoization outside of React. It boils down to using custom-made solutions like Maps or serialization. This is a problem because engineers implementing and reviewing solutions for memoization outside of React have to sink time into writing and creating a custom solution that may not be consistent with other places in the codebase. This leads to inconsistency, overhead, and at times sub-optimal solutions.

Can you give some examples of such scenarios and where we encounter this problem?

@roryabraham
Copy link
Contributor

Can you give some examples of such scenarios and where we encounter this problem?

Here are just a few examples of different caching solutions we've built ad-hoc:

A case study I was involved with can be found in this PR. The diff in src/libs/Localize/index.ts could have been reduced to this:

const translateMemoized = moize(translate);
export {translateMemoized as translate};

and lots of discussion could have been avoided with this standardization.

@janicduplessis
Copy link
Contributor

janicduplessis commented May 16, 2024

Other case I added recently that could use this

const thumbnailDimensionsCache = new Map<string, {width: number; height: number}>();

@puneetlath
Copy link
Contributor

@kacper-mikolajczak can you please post this in the #expensify-open-source channel in problem/solution format along with all the information provided in the OP? And cc @app-deployers on it. Thank you!

@kacper-mikolajczak
Copy link
Contributor Author

Sure thing @puneetlath! Here is a P/S post.

@tgolen
Copy link
Contributor

tgolen commented May 22, 2024

Number of releases in the last year: 5

From looking at https://github.com/planttheidea/moize/releases, it looks like the last release was May 2023, last year. Correct?

@puneetlath
Copy link
Contributor

Looks like the discussion is ongoing.

@melvin-bot melvin-bot bot added the Overdue label May 31, 2024
@kacper-mikolajczak
Copy link
Contributor Author

Proposal

Intro

Goal of the proposal is to find API for a future memoization standard. By looking at the current use-cases in the codebase, we will try to distill minimal API surface which is going to be used for the implementation.

Examples

Lodash memoize helpers

There are two instances of lodash memoize helper in the app. Both of them are meant to be replaced with suggested solution.

The getEmojiUnicode helper has simple API with just one input, so it is going to be straightforward to replace it. No extra requirements.

const getEmojiUnicode = memoize((input: string) => {

Same goes for second use-case which is getLocaleDigits.

const getLocaleDigits = _.memoize((locale: Locale): string[] => {

Intl-like modules

Intl as a module needs to be memoized in order not to re-create new instances on every call (especially when used in a iteration with same configuration, e.g. rendering list of components).

#40341

This use-case requires deep comparison of arguments, because options passed to Intl methods are possibly going to be the same across the app, but have different references.

Maps

Many samples of using Maps were provided, like ones below:

Based on those examples we would need to employ value caching mechanism (instead of function caching) which could be achieved by overloading memoize API or creating a separate like Cache.

Requirements

Here are additional concerns and requirements that were discovered either during discussion or exploration of similar solutions (moize, memoizee etc.):

  • Very simple API like moize (just wrap the function, and that's it)
  • Arbitrary data (strings, numbers, arrays, objects, maps) as input arguments
  • Performance considerations regarding Array vs Map throughput
  • Key serialization
    • Sensitive to order of arguments
    • Circular dependencies
  • Cache invalidation strategy
  • Original function static properties
    • It may be a good idea to copy static properties but based on current use-cases it is not needed see

Conclusion

Based on findings above and recent discussion, we can conclude that in simplest form the API could look like it:

type MapCacheConfig = {
    cacheMode: 'map';
    // Map keys are singlular values, so we cannot compare tuple of arguments directly. We are forced to serialize arguments and then compare strings.
    // It may be worth to choose if you anticipate large cache size.
    equalityCheck: 'deep';
};

type ArrayCacheConfig = {
    cacheMode: 'array';
    equalityCheck: 'shallow' | 'deep';
};

type CacheConfig = MapCacheConfig | ArrayCacheConfig;

type MemoizeConfig = {
    maxSize: number;
    maxAge: number;
    replacementPolicy: 'LRU';
} & CacheConfig;

type MemoizeStaticInstance<T> = {
    get: (key: string) => T | undefined;
    set: (key: string, value: T) => void;
    clear: () => void;
} 

type MemoizeInstance<Fn extends () => {}> = Fn & MemoizeStaticInstance<ReturnType<Fn>>;

type Memoize<Fn extends () => {}> = (f: Fn, config: MemoizeConfig) => MemoizeInstance<Fn>;
type Memoize<T> = (initialValue T[], config: MemoizeConfig) => MemoizeStaticInstance<T>;

In the next comment I will add information about possible implementation obstacles. Let me know what you think, thanks!

@melvin-bot melvin-bot bot added Daily KSv2 Overdue and removed Weekly KSv2 Overdue labels Jun 4, 2024
Copy link

melvin-bot bot commented Jun 7, 2024

@puneetlath Whoops! This issue is 2 days overdue. Let's get this updated quick!

@puneetlath puneetlath added Weekly KSv2 and removed Daily KSv2 labels Jun 7, 2024
@melvin-bot melvin-bot bot removed the Overdue label Jun 7, 2024
@mountiny
Copy link
Contributor

@kacper-mikolajczak What is your ETA for this POC?

@kacper-mikolajczak
Copy link
Contributor Author

Hi @mountiny I have posted POC here: #43538.

I will cross-post the update in the Slack thread as well - let me know what you think, thanks!

@melvin-bot melvin-bot bot added the Overdue label Jun 20, 2024
@puneetlath
Copy link
Contributor

@kacper-mikolajczak what's the next step here?

@melvin-bot melvin-bot bot removed the Overdue label Jun 25, 2024
@roryabraham
Copy link
Contributor

@kacper-mikolajczak has a POC for a custom-build general purpose memoization tool (not moize) here. It went through some reviews but he's OOO this week so I assume it will pick back up next week

@melvin-bot melvin-bot bot added the Overdue label Jul 3, 2024
@puneetlath
Copy link
Contributor

How's it going @kacper-mikolajczak?

@melvin-bot melvin-bot bot removed the Overdue label Jul 3, 2024
@mountiny
Copy link
Contributor

mountiny commented Jul 3, 2024

@puneetlath i believe this is now waiting for @roryabraham to check the changes made after his previous review

@kacper-mikolajczak
Copy link
Contributor Author

Hi @puneetlath, exactly as @mountiny said 🫡

@melvin-bot melvin-bot bot added Reviewing Has a PR in review Weekly KSv2 and removed Weekly KSv2 labels Jul 8, 2024
@roryabraham
Copy link
Contributor

I reviewed and approved the PR last week. Looks like @kacper-mikolajczak has an updated TODO list here

@mountiny
Copy link
Contributor

We are getting close, I think we can merge the PR tomorrow

@melvin-bot melvin-bot bot added Weekly KSv2 Awaiting Payment Auto-added when associated PR is deployed to production and removed Weekly KSv2 labels Jul 26, 2024
@melvin-bot melvin-bot bot changed the title Moize - general purpose memoization tool [HOLD for payment 2024-08-02] Moize - general purpose memoization tool Jul 26, 2024
Copy link

melvin-bot bot commented Jul 26, 2024

Reviewing label has been removed, please complete the "BugZero Checklist".

@melvin-bot melvin-bot bot removed the Reviewing Has a PR in review label Jul 26, 2024
Copy link

melvin-bot bot commented Jul 26, 2024

The solution for this issue has been 🚀 deployed to production 🚀 in version 9.0.12-0 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:

If no regressions arise, payment will be issued on 2024-08-02. 🎊

For reference, here are some details about the assignees on this issue:

@puneetlath
Copy link
Contributor

Adding @mananjadhav as it looks like they were the C+ here.

@melvin-bot melvin-bot bot added Daily KSv2 and removed Weekly KSv2 labels Aug 1, 2024
Copy link

melvin-bot bot commented Aug 2, 2024

Payment Summary

Upwork Job

BugZero Checklist (@puneetlath)

  • I have verified the correct assignees and roles are listed above and updated the neccesary manual offers
  • I have verified that there are no duplicate or incorrect contracts on Upwork for this job (https://www.upwork.com/ab/applicants//hired)
  • I have paid out the Upwork contracts or cancelled the ones that are incorrect
  • I have verified the payment summary above is correct

@puneetlath
Copy link
Contributor

Payment summary:

@JmillsExpensify
Copy link

$250 approved for @mananjadhav

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
AutoAssignerAppLibraryReview Auto assign someone to review a new library being added to App Awaiting Payment Auto-added when associated PR is deployed to production Daily KSv2
Projects
None yet
Development

No branches or pull requests

8 participants