2020#
2121import itertools
2222import logging
23+ from enum import Enum
2324from typing import (
2425 TYPE_CHECKING ,
2526 AbstractSet ,
112113SyncRequestKey = Tuple [Any , ...]
113114
114115
116+ class SyncVersion (Enum ):
117+ """
118+ Enum for specifying the version of sync request. This is used to key which type of
119+ sync response that we are generating.
120+
121+ This is different than the `sync_type` you might see used in other code below; which
122+ specifies the sub-type sync request (e.g. initial_sync, full_state_sync,
123+ incremental_sync) and is really only relevant for the `/sync` v2 endpoint.
124+ """
125+
126+ # These string values are semantically significant because they are used in the the
127+ # metrics
128+
129+ # Traditional `/sync` endpoint
130+ SYNC_V2 = "sync_v2"
131+
132+
115133@attr .s (slots = True , frozen = True , auto_attribs = True )
116134class SyncConfig :
117135 user : UserID
@@ -309,13 +327,25 @@ async def wait_for_sync_for_user(
309327 self ,
310328 requester : Requester ,
311329 sync_config : SyncConfig ,
330+ sync_version : SyncVersion ,
312331 since_token : Optional [StreamToken ] = None ,
313332 timeout : int = 0 ,
314333 full_state : bool = False ,
315334 ) -> SyncResult :
316335 """Get the sync for a client if we have new data for it now. Otherwise
317336 wait for new data to arrive on the server. If the timeout expires, then
318337 return an empty sync result.
338+
339+ Args:
340+ requester: The user requesting the sync response.
341+ sync_config: Config/info necessary to process the sync request.
342+ sync_version: Determines what kind of sync response to generate.
343+ since_token: The point in the stream to sync from.
344+ timeout: How long to wait for new data to arrive before giving up.
345+ full_state: Whether to return the full state for each room.
346+
347+ Returns:
348+ When `SyncVersion.SYNC_V2`, returns a full `SyncResult`.
319349 """
320350 # If the user is not part of the mau group, then check that limits have
321351 # not been exceeded (if not part of the group by this point, almost certain
@@ -327,6 +357,7 @@ async def wait_for_sync_for_user(
327357 sync_config .request_key ,
328358 self ._wait_for_sync_for_user ,
329359 sync_config ,
360+ sync_version ,
330361 since_token ,
331362 timeout ,
332363 full_state ,
@@ -338,6 +369,7 @@ async def wait_for_sync_for_user(
338369 async def _wait_for_sync_for_user (
339370 self ,
340371 sync_config : SyncConfig ,
372+ sync_version : SyncVersion ,
341373 since_token : Optional [StreamToken ],
342374 timeout : int ,
343375 full_state : bool ,
@@ -363,9 +395,11 @@ async def _wait_for_sync_for_user(
363395 else :
364396 sync_type = "incremental_sync"
365397
398+ sync_label = f"{ sync_version } :{ sync_type } "
399+
366400 context = current_context ()
367401 if context :
368- context .tag = sync_type
402+ context .tag = sync_label
369403
370404 # if we have a since token, delete any to-device messages before that token
371405 # (since we now know that the device has received them)
@@ -384,14 +418,16 @@ async def _wait_for_sync_for_user(
384418 # we are going to return immediately, so don't bother calling
385419 # notifier.wait_for_events.
386420 result : SyncResult = await self .current_sync_for_user (
387- sync_config , since_token , full_state = full_state
421+ sync_config , sync_version , since_token , full_state = full_state
388422 )
389423 else :
390424 # Otherwise, we wait for something to happen and report it to the user.
391425 async def current_sync_callback (
392426 before_token : StreamToken , after_token : StreamToken
393427 ) -> SyncResult :
394- return await self .current_sync_for_user (sync_config , since_token )
428+ return await self .current_sync_for_user (
429+ sync_config , sync_version , since_token
430+ )
395431
396432 result = await self .notifier .wait_for_events (
397433 sync_config .user .to_string (),
@@ -416,13 +452,14 @@ async def current_sync_callback(
416452 lazy_loaded = "true"
417453 else :
418454 lazy_loaded = "false"
419- non_empty_sync_counter .labels (sync_type , lazy_loaded ).inc ()
455+ non_empty_sync_counter .labels (sync_label , lazy_loaded ).inc ()
420456
421457 return result
422458
423459 async def current_sync_for_user (
424460 self ,
425461 sync_config : SyncConfig ,
462+ sync_version : SyncVersion ,
426463 since_token : Optional [StreamToken ] = None ,
427464 full_state : bool = False ,
428465 ) -> SyncResult :
@@ -431,12 +468,26 @@ async def current_sync_for_user(
431468 This is a wrapper around `generate_sync_result` which starts an open tracing
432469 span to track the sync. See `generate_sync_result` for the next part of your
433470 indoctrination.
471+
472+ Args:
473+ sync_config: Config/info necessary to process the sync request.
474+ sync_version: Determines what kind of sync response to generate.
475+ since_token: The point in the stream to sync from.p.
476+ full_state: Whether to return the full state for each room.
477+ Returns:
478+ When `SyncVersion.SYNC_V2`, returns a full `SyncResult`.
434479 """
435480 with start_active_span ("sync.current_sync_for_user" ):
436481 log_kv ({"since_token" : since_token })
437- sync_result = await self .generate_sync_result (
438- sync_config , since_token , full_state
439- )
482+ # Go through the `/sync` v2 path
483+ if sync_version == SyncVersion .SYNC_V2 :
484+ sync_result : SyncResult = await self .generate_sync_result (
485+ sync_config , since_token , full_state
486+ )
487+ else :
488+ raise Exception (
489+ f"Unknown sync_version (this is a Synapse problem): { sync_version } "
490+ )
440491
441492 set_tag (SynapseTags .SYNC_RESULT , bool (sync_result ))
442493 return sync_result
0 commit comments