The ClientTagBasedModelTypeProcessor is a crucial piece of the USS codepath. It lives on the model thread and performs the tracking of sync metadata for the ModelTypeSyncBridge that owns it by implementing the ModelTypeChangeProcessor interface, as well as sending commit requests to the ModelTypeWorker on the sync thread via the CommitQueue interface and receiving updates from the same worker via the ModelTypeProcessor interface.
This processor supports types that use a client tag, which is currently includes all except bookmarks. This means all changes in flight (either incoming remote changes provided via the ModelTypeWorker, or local changes reported by the ModelTypeSyncBridge) must specify a client tag, which is considered (after being hashed) the main global identifier of a sync entity.
The bridge owns a processor object at all times and operates on the same thread as it. If sync is disabled, the processor is destroyed but a new one is immediately created to replace it.
The processor sits between the model bridge and the sync engine. It has knowledge of what state each is in based on the calls it has receieved and performed. The states are not stored explicitly, but are implicit based on state stored in the processor. Here are the states of each, with notes on their transitions and how to determine them.
UNREADYModelReadyToStart to be called.waiting_for_metadata_ && !model_error_NEEDS_DATAwaiting_for_pending_data_ && !model_error_READY!waiting_for_metadata_ && !waiting_for_pending_data && !model_errorERROR!!model_error_DISCONNECTED!error_handler_.STARTEDREADY (or ERROR).error_handler_ && start_callback_CONNECT_PENDINGERROR, the error is passed along and the callback is cleared; we're really waiting for DisableSync instead of connect.error_handler_ && !start_callback_CONNECTEDCommitQueue that passes changes to the ModelTypeWorker on the sync thread.!!worker_Based on the interplay of the model and sync states, the processor effectively progresses through 3 states worth noting:
UNINITIALIZEDPut and Delete calls are not allowed in this state (will DCHECK).NOT_TRACKINGPut and Delete calls will be ignored.ModelTypeState::initial_sync_done is false).IsTrackingMetadata for optimization, not correctness.TRACKINGPut and Delete calls must happen for entity changes.ModelTypeState::initial_sync_done is true).SYNCINGTRACKING.TRACKING, it progresses to this state as soon as it gets connected to the worker.NOT_TRACKING, it progresses to this state after MergeSyncData is called and the metadata is initialized.The ProcessorEntity tracks the state of individual entities for the processor. It keeps the EntityMetadata proto in memory, as well as any pending commit data until it gets acked by the server. It also stores the special commit_requested_sequence_number_, which tracks the sequence number of the last version that's been sent to the server.
The tracker holds the metadata in memory forever, which is needed so we know what to update the on-disk memory with when we get a new local or remote change. Changing this would require being able to handle updates asynchronously.