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

[WIP] [simple-cache-provider] Subscriptions #13216

Closed
wants to merge 5 commits into from

Conversation

acdlite
Copy link
Collaborator

@acdlite acdlite commented Jul 16, 2018

Depends on #13139

Adds subscription support to simple-cache-provider. A subscription is created the first time a value is read from the cache, and disposed once we detect that all the consumers have unmounted.

On the initial mount, subscriptions are stored in a special map on the nearest provider (_pendingChildSubscriptionsMap). When the initial mount commits, the subscriptions are transferred from the pending set to the newly mounted provider.

The advantage of this approach over the one used by the create-subscription package (and most third-party libraries) is that the context API is used to ensure consistency: if multiple components read the same value from the cache, they will always receive the same value. Subscriptions are created per key, not per component.

Because consistency is guaranteed between components, it's ok if the tree is out of sync with the latest subscription value. We never have to revert back to sync mode. In other words, the React tree is eventually consistent with the subscription, but multiple components within a single React tree are always consistent with each other.

TODO:

  • cache.purge
  • cache.preload
  • Use the calculateChangedBits API to optimize subscription updates
  • Use a separate context type per resource, instead of one shared context. (We may want to hold off on this until we have automatic injection of context providers.)
  • More tests

Follow ups:

  • This library would really benefit from automatic injection of context providers.

@pull-bot
Copy link

pull-bot commented Jul 16, 2018

React: size: 🔺+2.4%, gzip: 🔺+1.9%

ReactDOM: size: 🔺+0.7%, gzip: 🔺+0.7%

Details of bundled changes.

Comparing: 21ac62c...0830626

react

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react.development.js +0.8% +0.8% 57.39 KB 57.85 KB 16.03 KB 16.16 KB UMD_DEV
react.production.min.js 🔺+2.4% 🔺+1.9% 6.86 KB 7.03 KB 2.91 KB 2.96 KB UMD_PROD
react.development.js +0.9% +0.9% 51.58 KB 52.04 KB 14.21 KB 14.33 KB NODE_DEV
react.production.min.js 🔺+2.8% 🔺+2.3% 5.87 KB 6.03 KB 2.51 KB 2.57 KB NODE_PROD
React-dev.js +0.9% +0.9% 49.86 KB 50.31 KB 13.78 KB 13.9 KB FB_WWW_DEV
React-prod.js 🔺+2.4% 🔺+1.9% 13.4 KB 13.72 KB 3.73 KB 3.8 KB FB_WWW_PROD

react-dom

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-dom.development.js +0.2% +0.2% 640.8 KB 642.26 KB 150.28 KB 150.64 KB UMD_DEV
react-dom.production.min.js 🔺+0.7% 🔺+0.7% 95.49 KB 96.2 KB 30.89 KB 31.12 KB UMD_PROD
react-dom.development.js +0.2% +0.2% 636.94 KB 638.4 KB 149.09 KB 149.46 KB NODE_DEV
react-dom.production.min.js 🔺+0.7% 🔺+0.9% 95.48 KB 96.19 KB 30.41 KB 30.67 KB NODE_PROD
ReactDOM-dev.js +0.4% +0.3% 643.9 KB 646.31 KB 147.6 KB 148.02 KB FB_WWW_DEV
ReactDOM-prod.js 🔺+0.7% 🔺+0.7% 276.67 KB 278.64 KB 51.72 KB 52.11 KB FB_WWW_PROD
react-dom.profiling.min.js +0.8% +0.9% 96.57 KB 97.32 KB 30.8 KB 31.07 KB NODE_PROFILING
ReactDOM-profiling.js +0.8% +0.8% 279.67 KB 281.86 KB 52.39 KB 52.82 KB FB_WWW_PROFILING

react-art

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-art.development.js +0.4% +0.4% 426 KB 427.5 KB 96.1 KB 96.46 KB UMD_DEV
react-art.production.min.js 🔺+1.0% 🔺+1.1% 82.71 KB 83.5 KB 25.5 KB 25.77 KB UMD_PROD
react-art.development.js +0.4% +0.4% 358.56 KB 360.02 KB 79.03 KB 79.38 KB NODE_DEV
react-art.production.min.js 🔺+1.7% 🔺+2.0% 47.69 KB 48.49 KB 14.88 KB 15.17 KB NODE_PROD
ReactART-dev.js +0.7% +0.6% 348.46 KB 350.87 KB 73.96 KB 74.4 KB FB_WWW_DEV
ReactART-prod.js 🔺+1.5% 🔺+1.6% 147.75 KB 149.89 KB 25 KB 25.39 KB FB_WWW_PROD

react-test-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-test-renderer.development.js +0.4% +0.4% 362.88 KB 364.35 KB 79.55 KB 79.9 KB UMD_DEV
react-test-renderer.production.min.js 🔺+1.6% 🔺+2.1% 48.59 KB 49.39 KB 14.97 KB 15.29 KB UMD_PROD
react-test-renderer.development.js +0.4% +0.4% 359.01 KB 360.48 KB 78.58 KB 78.93 KB NODE_DEV
react-test-renderer.production.min.js 🔺+1.6% 🔺+2.2% 48.31 KB 49.1 KB 14.79 KB 15.11 KB NODE_PROD
ReactTestRenderer-dev.js +0.7% +0.6% 363.87 KB 366.29 KB 77.59 KB 78.04 KB FB_WWW_DEV

react-reconciler

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-reconciler.development.js +0.4% +0.5% 346.95 KB 348.42 KB 74.94 KB 75.3 KB NODE_DEV
react-reconciler.production.min.js 🔺+1.5% 🔺+2.0% 47.1 KB 47.8 KB 14.13 KB 14.41 KB NODE_PROD
react-reconciler-persistent.development.js +0.4% +0.5% 345.57 KB 347.03 KB 74.38 KB 74.74 KB NODE_DEV
react-reconciler-persistent.production.min.js 🔺+1.5% 🔺+2.0% 47.11 KB 47.81 KB 14.13 KB 14.41 KB NODE_PROD

simple-cache-provider

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
simple-cache-provider.development.js +167.1% +98.6% 8.79 KB 23.49 KB 2.83 KB 5.62 KB NODE_DEV
simple-cache-provider.production.min.js 🔺+272.8% 🔺+185.2% 1.63 KB 6.07 KB 827 B 2.3 KB NODE_PROD
SimpleCacheProvider-dev.js +150.9% +87.7% 9.29 KB 23.3 KB 2.89 KB 5.42 KB FB_WWW_DEV
SimpleCacheProvider-prod.js 🔺+284.7% 🔺+185.0% 3.63 KB 13.95 KB 1.1 KB 3.14 KB FB_WWW_PROD

react-native-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactNativeRenderer-dev.js +0.5% +0.5% 481.57 KB 483.9 KB 106.48 KB 106.97 KB RN_FB_DEV
ReactNativeRenderer-prod.js 🔺+1.1% 🔺+1.3% 212.78 KB 215.02 KB 37 KB 37.49 KB RN_FB_PROD
ReactNativeRenderer-dev.js +0.5% +0.5% 481.3 KB 483.64 KB 106.43 KB 106.91 KB RN_OSS_DEV
ReactNativeRenderer-prod.js 🔺+1.4% 🔺+1.5% 202.27 KB 205.1 KB 35.36 KB 35.88 KB RN_OSS_PROD
ReactFabric-dev.js +0.5% +0.5% 471.78 KB 474.12 KB 104.05 KB 104.55 KB RN_FB_DEV
ReactFabric-prod.js 🔺+1.6% 🔺+1.7% 193.15 KB 196.3 KB 33.78 KB 34.35 KB RN_FB_PROD
ReactFabric-dev.js +0.5% +0.5% 471.81 KB 474.15 KB 104.07 KB 104.57 KB RN_OSS_DEV
ReactFabric-prod.js 🔺+1.6% 🔺+1.7% 193.19 KB 196.33 KB 33.79 KB 34.37 KB RN_OSS_PROD
ReactNativeRenderer-profiling.js +1.5% +1.5% 205.4 KB 208.43 KB 36.05 KB 36.59 KB RN_OSS_PROFILING
ReactFabric-profiling.js +1.7% +1.7% 195.96 KB 199.3 KB 34.4 KB 34.98 KB RN_OSS_PROFILING
ReactNativeRenderer-profiling.js +1.1% +1.4% 215.86 KB 218.31 KB 37.69 KB 38.2 KB RN_FB_PROFILING
ReactFabric-profiling.js +1.7% +1.7% 195.92 KB 199.26 KB 34.38 KB 34.97 KB RN_FB_PROFILING

Generated by 🚫 dangerJS

Currently, context can only be read by a special type of component,
ContextConsumer. We want to add support to all fibers, including
classes and functional components.

Each fiber may read from one or more contexts. To enable quick, mono-
morphic access of this list, we'll store them on a fiber property.
unstable_read can be called anywhere within the render phase. That
includes the render method, getDerivedStateFromProps, constructors,
functional components, and context consumer render props.

If it's called outside the render phase, an error is thrown.
Currently, the `expirationTime` field represents the pending work of
both the fiber itself — including new props, state, and context — and of
any updates in that fiber's subtree.

This commit adds a second field called `childExpirationTime`. Now
`expirationTime` only represents the pending work of the fiber itself.
The subtree's pending work is represented by `childExpirationTime`.

The biggest advantage is it requires fewer checks to bailout on already
finished work. For most types of work, if the `expirationTime` does not
match the render expiration time, we can bailout immediately without
any further checks. This won't work for fibers that have
`shouldComponentUpdate` semantics (class components), for which we still
need to check for props and state changes explicitly.
Adds subscription support. A subscription is created the first time
a value is read from the cache, and disposed once we detect that all
the consumers have unmounted.

On the initial mount, subscriptions are stored in a special map on the
nearest provider (`_pendingChildSubscriptionsMap`). When the initial
mount commits, the subscriptions are transferred from the pending set
to the newly mounted provider.
@acdlite
Copy link
Collaborator Author

acdlite commented Aug 7, 2018

Closed in favor of #13337

@acdlite acdlite closed this Aug 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants