Status Update
Comments
ad...@google.com <ad...@google.com> #2
P2 for consideration as what GlobalSnapshotManager does is available as public API and the operations involved are idempotent, however it involves making some deliberate decisions around threading behavior if the goal is to run host-side tests. In many cases it makes testing much easier and more deliberate/deterministic to perform snapshot commits/global apply notifications explicitly in those tests. Tools such as Snapshot.asContextElement()
and related approaches for scoping snapshot changes are also a factor.
al...@google.com <al...@google.com> #3
Triage notes, question is should the concept of Snapshot
and GlobalSnapshotManager
be moved out of Compose Runtime? Probably, but writing your own snapshot manager is ~2 LoC and it wouldn't conflict with the Compose snapshot manager.
The difficulty of extracting it out of runtime is that (1) we can't change the class name or package and (2) there are some internal aspects of snapshots that might require new public APIs.
mutableSnapshotOf
would need to move, as well, which makes the packaging even uglier. Not fatal, though.
al...@google.com <al...@google.com> #4
Triage notes, blocked by moving snapshots to its own module. Handing off to Chuck for further triage.
ch...@google.com <ch...@google.com> #5
The GlobalSnapshotManager
is in the UI module and uses public API from the snapshot system. It uses Snpashot.registerGlobalWriteObserver
and Snapshot.sendApplyNotifications()
both of which are public API. The reason there is a only one GlobalSnapshotManager
in an application is because adding a write observer adds overhead to every write to a snapshot object. Using a shared instance limits this overhead. The write observer is not necessary in tests, however, as a test can just call Snapshot.sendApplyNotifications()
directly whenever needed or can set up a scoped write observer that is removed when the test completes.
That said, as Alan points out, the GlobalSnapshotManager
can be made public but should be made public when, if, the snapshot system moves out of the compose runtime module as described in
al...@google.com <al...@google.com> #6
Triage notes: We're doing this indirectly and we will have a public API that accomplishes the same thing.
al...@google.com <al...@google.com> #7
Triage notes: Workaround is still valid, no ETA on a public API but it's still something we are pursuing. Marking as dependent on bug for that API.
bu...@google.com <bu...@google.com> #8
Bugjuggler:
Description
snapshotFlow
converts snapshot state into aFlow
for consumption.However, it does this by
Snapshot.registerApplyObserver
, which is only called when snapshot state has been applied.In normal Compose UI usage,
Snapshot.sendApplyNotifications
is regularly called due to a "heartbeat" setup by the internalGlobalSnapshotManager
, sosnapshotFlow
functions as expected.If
GlobalSnapshotManager
hasn't been setup, however,snapshotFlow
will never be called with updates.Consider the following scenario, in an app with both Compose and View code, and is using
snapshotFlow
inViewModel
s:snapshotFlow
in theViewModel
Whether or not
snapshotFlow
emits updates depends on whether or not Fragment B (with its ComposeView) has been seen yet or not.This directly impacts the viability of using snapshot state in the data layer or
ViewModel
, without a way to ensure these normal heartbeats are started.One potential resolution here is to expose
GlobalSnapshotManager
outside of the library, so that consumers can ensure heartbeats are being sent.