matterandvoid-space / subscriptions

A subscriptions library over a source of data (forked + extracted from re-frame)
Other
50 stars 1 forks source link

Performance idea: dynamic layer2 sub #32

Closed dvingo closed 4 months ago

dvingo commented 1 year ago

Use-case: A layer2 subscription for a ref like [::user/id <user-id>] where the user-id is itself coming from the app db. At first that value will be nil and later will be populated due to some event.

Examples where this happens:

Goal:

We want to implement this with a Cursor for optimal performance like all layer2 subscriptions - but due to subscriptions being cached once that path is determined (as [::user-id nil] on first render) then it cannot be changed.

The idea is to implement a macro that will return a Reaction if the id value is nil but once it is populated will replace itself in the subscription cache with a Cursor. I think it will also need to handle the case where the pointed to id value changes, like in the edit example above. Not sure how feasible this will be in practice, but making adding this note to investigate it.

dvingo commented 4 months ago

This was partially addressed by not caching layer 2 subs that return nil https://github.com/matterandvoid-space/subscriptions/commit/911834a8b391814fb4a148a4a0750941722fcdc7

That logic could be updated to support not caching a layer 2 sub whose last path value is nil as well.

dvingo commented 4 months ago

Just tested this again and this is already working because the https://github.com/matterandvoid-space/subscriptions/blob/mainline/src/main/space/matterandvoid/subscriptions/impl/fulcro.cljc#L60 subscription arguments hashmap is part of the cache key.

The original issue was due to the first implementation memoizing the subscription functions themselves which would have caused the bug described in the issue. Because of bugs like this that was removed - the problem is due to indirection. If a subscription takes an argument which it uses as part of a path into app-db, memoizing that function will lead to erroneous caching problems where the target value changes but the subscription to access that target value is memoized and thus will never return the new indirect value.