Giter VIP home page Giter VIP logo

Comments (11)

blackarctic avatar blackarctic commented on August 21, 2024

Happy to make a PR for this, but want to ensure interest first.

from memoizee.

Rush avatar Rush commented on August 21, 2024

From a user's perspective of memoizee it makes sense. Would be useful for some use-cases like memoizing connections and other resources that don't technically change but are expensive to maintain.

from memoizee.

medikoo avatar medikoo commented on August 21, 2024

@blackarctic great thanks for this proposal. Still, wouldn't combining maxAge with max address this use case reliably?

Having that setup only max of last accessed items will be kept but for no longer than maxAge.

from memoizee.

medikoo avatar medikoo commented on August 21, 2024

Also @blackarctic can you outline what is the specific use case?

from memoizee.

blackarctic avatar blackarctic commented on August 21, 2024

I don’t believe the existing combination accomplishes this goal. Combing maxAge and max says “I want to keep a max of x items in the cache for no longer than y milliseconds after first access”. Using just maxAgeSinceAccess says “I want to keep any number of items in the cache as long as they have been accessed in the last y milliseconds”. Combining maxAgeSinceAccess and max would give us “I want to keep a max of x items in the cache for no longer than y milliseconds after last access”.

As mentioned in the description, this use case of keeping items in the cache since last access (as opposed to first access) makes much more sense to me than maxAge, since we likely don't want to expire a memoized value that is actively being used. preFetch also doesn't make much sense as we likely have no need to recompute the value. We simply want to remove inactive items from the cache and keep active items in the cache.

from memoizee.

medikoo avatar medikoo commented on August 21, 2024

this use case of keeping items in the cache since last access (as opposed to first access)

This explains what you want, but does not describe the use case you have (what are you caching? Why last access dictates the freshness of a cached value, and not the retrieval timestamp ?)

Note it's a very first request like that (in near 9 years of this package being around). Either we're addressing a very rare use case, or this use case can be addressed in a better way.

from memoizee.

blackarctic avatar blackarctic commented on August 21, 2024

Sure. Let’s say you want to memoize the conversion from any number of objects from shape A to shape B. You want to keep the object references the same so preFetch isn’t going to work because that will create new object references. You also don’t know how many you will have so you can’t use max. You can use maxAge but after x amount of time, the object references will be dropped and you will get bugs because you need the object references to persist. What we actually want is to persist the object references as long as they are actively being accessed.

I apologize, it’s hard for me to come up with specific examples because I feel almost every memoization example that uses maxAge is better served with maxAgeSinceAccess. Simple reason is don’t remove cached items that are actively being used.

from memoizee.

Rush avatar Rush commented on August 21, 2024

I often memoize observables which keep subscribed to some resource, such as redis events or to a websocket. Such resource never changes so the goal of memoization is to just keep it active for as long as it's needed.

maxAge is best for cases when things generally change over time such as:

  • memoizing number of documents the user owns
  • memoizing statistics of service usage
    Both statistics and documents always change so maxAgeSinceAccess would not make any sense. These numbers need to be expired to generate a new value.

But if you're memoizing:

  • An operating system handle (file, connection)
  • Data stream
  • Lazy loaded service/class that needs to exist for a given input
    For these cases maxAgeSinceAccess will always be better.

from memoizee.

medikoo avatar medikoo commented on August 21, 2024

What we actually want is to persist the object references as long as they are actively being accessed.

@blackarctic Why in this specific case, it's ok to assume that if object wasn't accessed for at least X period, it's safe to remove from cache, and it's not safe to remove if it's the least recently accessed object from all cached objects when count of them reached Y count?

To me it looks a great max (LRU) use case, still, your description feels purely theoretical, Can you describe a real-world case you're dealing with?

I often memoize observables which keep subscribed to some resource, such as redis events or to a websocket. Such resource never changes so the goal of memoization is to just keep it active for as long as it's needed.

Thanks @Rush for your input. Wouldn't relying on weak option work best here? In that case, it'll be memoized as long as it's used by the consumers.

Otherwise is this a real need you have currently, or more a nice to have thing, that you assume you may benefit in some cases?

from memoizee.

blackarctic avatar blackarctic commented on August 21, 2024

@medikoo Sorry for the late reply. Looking back into this.

This situation I had in mind is a frontend render cycle, where max is not helpful because we can't limit by an arbitrary number since we can't know this arbitrary number beforehand. Essentially, in the frontend render cycle, we can actually safely assume that if our maxAgeSinceAccess is longer than it takes our render cycle to complete (including promises to resolve) then we can safely remove those references and all in the render cycle will have the same object. In this case, a maxAgeSinceAccess of a minute or two should be more than enough. With maxAgeSinceAccess pushing back the expiration on each access, it is impossible to have the memoized function return multiple references during the render cycle.

Render Cycle (using maxAgeSinceAccess)
  -> const a = getMemoizedValue() -  3ms --> Pushes back the expiration
  -> someOtherFunction() - 4ms
  -> const b = getMemoizedValue() - 3ms --> getMemoizedValue()'s cache has not expired. a is **equal** to b

Render Cycle (using maxAge)
  -> const a = getMemoizedValue() -  3ms --> Does not push back the expiration
  -> someOtherFunction() - 4ms
  -> const b = getMemoizedValue() - 3ms --> getMemoizedValue()'s cache has expired. a is **not equal** to b

from memoizee.

medikoo avatar medikoo commented on August 21, 2024

@blackarctic thanks for the explanations, still it still looks blurry to me.

Can you explain the use case without referring to the current memoizee API and without focusing on an eventual solution?

What exactly is the "Render Cycle" ? What is the "arbitrary number" you refer to?

(Also in memoizee maxAge as far as I remember is counted since function result resolved and not since the function was invoked)

from memoizee.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.