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

[IMP] lazy reactive computed value #1499

Closed
wants to merge 3 commits into from
Closed

Commits on Jan 3, 2024

  1. [IMP] lazy reactive computed value

    **Problem:** Prior to this commit, existing implementations of computed values
    are eager. An example is the `withComputedProperties` in odoo's web addon, see:
    [^1]. It has an issue such that it can lead to triggering of the compute
    function even if the target is still in invalid state -- e.g. removing an item
    in an array. This can be solved by batching the recomputation with `batched`.
    But once the compute is batched, the computed value can't be used by other
    computed values, because it won't recompute until the next tick -- it's not part
    of the same synchronous context.
    
    **Proposed solution:** This commit introduces a implementation of computed value
    that is pull-based -- it only recomputes when it's needed. The main logic is the
    following:
    
    - A computed value is declared with a single-parameter function wrapped with
      `computed`.
    - The compute function has a cache that stores the result of the computation.
    - The cached value is invalidated when one of the dependencies of the compute
      function changes.
      - During invalidation, the cache is only marked as invalid and the
        recomputation is not made.
    - A dependent computation such as an effect may indirectly depend in the
      dependencies of a computed value[^2]. This is an important detail because
      without this, the 'laziness' of the computed value won't trigger the dependent
      effect.
      - This indirect dependency tracking is achieved by using the introduced notion
        of multi-reactive target where a target can have multiple callbacks linked
        to it.
      - During recomputation of the computed value, both the target's reactive and
        the invalidation callback are subscribed to the dependencies of the computed
        value. But when the value is cached, only the target's reactive callback is
        subscribed.
    
    With this implementation, we achieve a lazy computed value that plays well with
    the existing reactive system.
    
    [^1]: https://github.com/odoo/odoo/blob/15d7cf12b98bf0223371b8cca91ef6f79c60ee31/addons/web/static/src/core/utils/reactive.js#L58
    [^2]: It's possible that in the dependency graph, an effect is affected by
    invalidation. This effect will be triggered which will potentially ask for the
    value of the computed value which will trigger the recomputation.
    caburj committed Jan 3, 2024
    Configuration menu
    Copy the full SHA
    51b2ea0 View commit details
    Browse the repository at this point in the history
  2. add new test for computed that sorts an array

    I had a discussion with SEB and he told me about auto-sort compute. He said that
    it would be better if we could implement automatic in-place sorting without
    triggering the reactivity.
    
    However, this PR can't actually handle that because this PR is just an extension
    of the existing reactivity, it doesn't actually modify it. So if inplace sort
    will result to multiple mutations, then that will be the number of times the
    callback will be called. Even inside a `computed` that's introduced in this PR.
    
    Nevertheless, compute that depends on sorted array is still useful, it's just
    that the sorting should not be done in-place. This commit introduces an example
    where a computed value that returns a sorted array is only called once (in a
    batched context) even though multiple mutations are made to the array.
    caburj committed Jan 3, 2024
    Configuration menu
    Copy the full SHA
    c38f021 View commit details
    Browse the repository at this point in the history

Commits on Jan 5, 2024

  1. sam's lazyComputed

    caburj committed Jan 5, 2024
    Configuration menu
    Copy the full SHA
    f124972 View commit details
    Browse the repository at this point in the history