1# ClientTagBasedModelTypeProcessor
2
3The [`ClientTagBasedModelTypeProcessor`][SMTP] is a crucial piece of the USS
4codepath. It lives on the model thread and performs the tracking of sync
5metadata for the [`ModelTypeSyncBridge`][MTSB] that owns it by implementing the
6[`ModelTypeChangeProcessor`][MTCP] interface, as well as sending commit requests
7to the [`ModelTypeWorker`][MTW] on the sync thread via the [`CommitQueue`][CQ]
8interface and receiving updates from the same worker via the
9[`ModelTypeProcessor`][MTP] interface.
10
11This processor supports types that use a client tag, which is currently
12includes all except bookmarks. This means all changes in flight (either incoming
13remote changes provided via the [`ModelTypeWorker`][MTW], or local changes
14reported by the [`ModelTypeSyncBridge`][MTSB]) must specify a client tag, which
15is considered (after being hashed) the main global identifier of a sync entity.
16
17[SMTP]: https://cs.chromium.org/chromium/src/components/sync/model_impl/client_tag_based_model_type_processor.h
18[MTSB]: https://cs.chromium.org/chromium/src/components/sync/model/model_type_sync_bridge.h
19[MTCP]: https://cs.chromium.org/chromium/src/components/sync/model/model_type_change_processor.h
20[MTW]: https://cs.chromium.org/chromium/src/components/sync/engine_impl/model_type_worker.h
21[CQ]: https://cs.chromium.org/chromium/src/components/sync/engine/commit_queue.h
22[MTP]: https://cs.chromium.org/chromium/src/components/sync/engine/model_type_processor.h
23
24[TOC]
25
26## Lifetime
27
28The bridge owns a processor object at all times and operates on the same thread
29as it. If sync is disabled, the processor is destroyed but a new one is
30immediately created to replace it.
31
32## Processor State Machines
33
34The processor sits between the model bridge and the sync engine. It has
35knowledge of what state each is in based on the calls it has receieved and
36performed. The states are not stored explicitly, but are implicit based on
37state stored in the processor. Here are the states of each, with notes on their
38transitions and how to determine them.
39
40### Model States
41
42*   `UNREADY`
43    *   Waiting for `ModelReadyToStart` to be called.
44    *   Determined by: `waiting_for_metadata_ && !model_error_`
45*   `NEEDS_DATA`
46    *   Waiting for data for pending commits to be loaded.
47    *   This state is skipped if there are no pending commits.
48    *   Determined by: `waiting_for_pending_data_ && !model_error_`
49*   `READY`
50    *   The model is completely ready to sync.
51    *   Determined by: `!waiting_for_metadata_ && !waiting_for_pending_data &&
52        !model_error`
53*   `ERROR`
54    *   Something in the model or storage broke.
55    *   This state is permanent until DisableSync destroys the object.
56    *   Determined by: `!!model_error_`
57
58### Sync States
59
60*   `DISCONNECTED`
61    *   Sync for this type has not started.
62    *   This state can be re-entered from any other state if Disconnect is
63        called.
64    *   Determined by: `!error_handler_`.
65*   `STARTED`
66    *   Sync has started but the model is not yet `READY` (or `ERROR`).
67    *   This state is skipped if the model is ready before sync is.
68    *   Determined by: `error_handler_ && start_callback_`
69*   `CONNECT_PENDING`
70    *   Both the model and sync are ready. The start callback has been called
71        and we're waiting to connect to the sync thread.
72    *   If the model was `ERROR`, the error is passed along and the callback is
73        cleared; we're really waiting for DisableSync instead of connect.
74    *   Determined by: `error_handler_ && !start_callback_`
75*   `CONNECTED`
76    *   We have a [`CommitQueue`][CQ] that passes changes to the
77        [`ModelTypeWorker`][MTW] on the sync thread.
78    *   Determined by: `!!worker_`
79
80### Processor States
81
82Based on the interplay of the model and sync states, the processor effectively
83progresses through 3 states worth noting:
84
85*   `UNINITIALIZED`
86    *    Metadata isn't loaded so we have no knowledge of entities.
87    *   `Put` and `Delete` calls are not allowed in this state (will DCHECK).
88*   `NOT_TRACKING`
89    *   Indicates that not metadata is being tracked and that `Put` and `Delete`
90        calls will be ignored.
91    *   This state is entered if the loaded metadata shows an initial merge
92        hasn't happened (`ModelTypeState::initial_sync_done` is false).
93    *   Exposed via `IsTrackingMetadata` for optimization, not correctness.
94*   `TRACKING`
95    *   Indicates that metadata is being tracked and `Put` and `Delete` calls
96        must happen for entity changes.
97    *   This state is entered if the loaded metadata shows an initial merge
98        has happened (`ModelTypeState::initial_sync_done` is true).
99*   `SYNCING`
100    *   Indicates that commits can be sent and updates can be received from the
101        sync server. This is a superstate of `TRACKING`.
102    *   If the processor was in `TRACKING`, it progresses to this state as soon
103        as it gets connected to the worker.
104    *   If the processor was in `NOT_TRACKING`, it progresses to this state
105        after `MergeSyncData` is called and the metadata is initialized.
106
107## Entity Tracker
108
109The [`ProcessorEntity`][PET] tracks the state of individual entities for
110the processor. It keeps the [`EntityMetadata`][EM] proto in memory, as well as
111any pending commit data until it gets acked by the server. It also stores the
112special `commit_requested_sequence_number_`, which tracks the sequence number of
113the last version that's been sent to the server.
114
115The tracker holds the metadata in memory forever, which is needed so we know
116what to update the on-disk memory with when we get a new local or remote change.
117Changing this would require being able to handle updates asynchronously.
118
119[PET]: https://cs.chromium.org/chromium/src/components/sync/model_impl/processor_entity.h
120[EM]: https://cs.chromium.org/chromium/src/components/sync/protocol/entity_metadata.proto
121