mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-05-02 10:06:05 -04:00
Add types to StreamToken and RoomStreamToken (#8279)
The intention here is to change `StreamToken.room_key` to be a `RoomStreamToken` in a future PR, but that is a big enough change without this refactoring too.
This commit is contained in:
parent
094896a69d
commit
63c0e9e195
5 changed files with 95 additions and 91 deletions
152
synapse/types.py
152
synapse/types.py
|
@ -18,7 +18,7 @@ import re
|
|||
import string
|
||||
import sys
|
||||
from collections import namedtuple
|
||||
from typing import Any, Dict, Mapping, MutableMapping, Tuple, Type, TypeVar
|
||||
from typing import Any, Dict, Mapping, MutableMapping, Optional, Tuple, Type, TypeVar
|
||||
|
||||
import attr
|
||||
from signedjson.key import decode_verify_key_bytes
|
||||
|
@ -362,22 +362,79 @@ def map_username_to_mxid_localpart(username, case_sensitive=False):
|
|||
return username.decode("ascii")
|
||||
|
||||
|
||||
class StreamToken(
|
||||
namedtuple(
|
||||
"Token",
|
||||
(
|
||||
"room_key",
|
||||
"presence_key",
|
||||
"typing_key",
|
||||
"receipt_key",
|
||||
"account_data_key",
|
||||
"push_rules_key",
|
||||
"to_device_key",
|
||||
"device_list_key",
|
||||
"groups_key",
|
||||
),
|
||||
@attr.s(frozen=True, slots=True)
|
||||
class RoomStreamToken:
|
||||
"""Tokens are positions between events. The token "s1" comes after event 1.
|
||||
|
||||
s0 s1
|
||||
| |
|
||||
[0] V [1] V [2]
|
||||
|
||||
Tokens can either be a point in the live event stream or a cursor going
|
||||
through historic events.
|
||||
|
||||
When traversing the live event stream events are ordered by when they
|
||||
arrived at the homeserver.
|
||||
|
||||
When traversing historic events the events are ordered by their depth in
|
||||
the event graph "topological_ordering" and then by when they arrived at the
|
||||
homeserver "stream_ordering".
|
||||
|
||||
Live tokens start with an "s" followed by the "stream_ordering" id of the
|
||||
event it comes after. Historic tokens start with a "t" followed by the
|
||||
"topological_ordering" id of the event it comes after, followed by "-",
|
||||
followed by the "stream_ordering" id of the event it comes after.
|
||||
"""
|
||||
|
||||
topological = attr.ib(
|
||||
type=Optional[int],
|
||||
validator=attr.validators.optional(attr.validators.instance_of(int)),
|
||||
)
|
||||
):
|
||||
stream = attr.ib(type=int, validator=attr.validators.instance_of(int))
|
||||
|
||||
@classmethod
|
||||
def parse(cls, string: str) -> "RoomStreamToken":
|
||||
try:
|
||||
if string[0] == "s":
|
||||
return cls(topological=None, stream=int(string[1:]))
|
||||
if string[0] == "t":
|
||||
parts = string[1:].split("-", 1)
|
||||
return cls(topological=int(parts[0]), stream=int(parts[1]))
|
||||
except Exception:
|
||||
pass
|
||||
raise SynapseError(400, "Invalid token %r" % (string,))
|
||||
|
||||
@classmethod
|
||||
def parse_stream_token(cls, string: str) -> "RoomStreamToken":
|
||||
try:
|
||||
if string[0] == "s":
|
||||
return cls(topological=None, stream=int(string[1:]))
|
||||
except Exception:
|
||||
pass
|
||||
raise SynapseError(400, "Invalid token %r" % (string,))
|
||||
|
||||
def as_tuple(self) -> Tuple[Optional[int], int]:
|
||||
return (self.topological, self.stream)
|
||||
|
||||
def __str__(self) -> str:
|
||||
if self.topological is not None:
|
||||
return "t%d-%d" % (self.topological, self.stream)
|
||||
else:
|
||||
return "s%d" % (self.stream,)
|
||||
|
||||
|
||||
@attr.s(slots=True, frozen=True)
|
||||
class StreamToken:
|
||||
room_key = attr.ib(type=str)
|
||||
presence_key = attr.ib(type=int)
|
||||
typing_key = attr.ib(type=int)
|
||||
receipt_key = attr.ib(type=int)
|
||||
account_data_key = attr.ib(type=int)
|
||||
push_rules_key = attr.ib(type=int)
|
||||
to_device_key = attr.ib(type=int)
|
||||
device_list_key = attr.ib(type=int)
|
||||
groups_key = attr.ib(type=int)
|
||||
|
||||
_SEPARATOR = "_"
|
||||
START = None # type: StreamToken
|
||||
|
||||
|
@ -385,15 +442,15 @@ class StreamToken(
|
|||
def from_string(cls, string):
|
||||
try:
|
||||
keys = string.split(cls._SEPARATOR)
|
||||
while len(keys) < len(cls._fields):
|
||||
while len(keys) < len(attr.fields(cls)):
|
||||
# i.e. old token from before receipt_key
|
||||
keys.append("0")
|
||||
return cls(*keys)
|
||||
return cls(keys[0], *(int(k) for k in keys[1:]))
|
||||
except Exception:
|
||||
raise SynapseError(400, "Invalid Token")
|
||||
|
||||
def to_string(self):
|
||||
return self._SEPARATOR.join([str(k) for k in self])
|
||||
return self._SEPARATOR.join([str(k) for k in attr.astuple(self)])
|
||||
|
||||
@property
|
||||
def room_stream_id(self):
|
||||
|
@ -435,63 +492,10 @@ class StreamToken(
|
|||
return self
|
||||
|
||||
def copy_and_replace(self, key, new_value):
|
||||
return self._replace(**{key: new_value})
|
||||
return attr.evolve(self, **{key: new_value})
|
||||
|
||||
|
||||
StreamToken.START = StreamToken(*(["s0"] + ["0"] * (len(StreamToken._fields) - 1)))
|
||||
|
||||
|
||||
class RoomStreamToken(namedtuple("_StreamToken", "topological stream")):
|
||||
"""Tokens are positions between events. The token "s1" comes after event 1.
|
||||
|
||||
s0 s1
|
||||
| |
|
||||
[0] V [1] V [2]
|
||||
|
||||
Tokens can either be a point in the live event stream or a cursor going
|
||||
through historic events.
|
||||
|
||||
When traversing the live event stream events are ordered by when they
|
||||
arrived at the homeserver.
|
||||
|
||||
When traversing historic events the events are ordered by their depth in
|
||||
the event graph "topological_ordering" and then by when they arrived at the
|
||||
homeserver "stream_ordering".
|
||||
|
||||
Live tokens start with an "s" followed by the "stream_ordering" id of the
|
||||
event it comes after. Historic tokens start with a "t" followed by the
|
||||
"topological_ordering" id of the event it comes after, followed by "-",
|
||||
followed by the "stream_ordering" id of the event it comes after.
|
||||
"""
|
||||
|
||||
__slots__ = [] # type: list
|
||||
|
||||
@classmethod
|
||||
def parse(cls, string):
|
||||
try:
|
||||
if string[0] == "s":
|
||||
return cls(topological=None, stream=int(string[1:]))
|
||||
if string[0] == "t":
|
||||
parts = string[1:].split("-", 1)
|
||||
return cls(topological=int(parts[0]), stream=int(parts[1]))
|
||||
except Exception:
|
||||
pass
|
||||
raise SynapseError(400, "Invalid token %r" % (string,))
|
||||
|
||||
@classmethod
|
||||
def parse_stream_token(cls, string):
|
||||
try:
|
||||
if string[0] == "s":
|
||||
return cls(topological=None, stream=int(string[1:]))
|
||||
except Exception:
|
||||
pass
|
||||
raise SynapseError(400, "Invalid token %r" % (string,))
|
||||
|
||||
def __str__(self):
|
||||
if self.topological is not None:
|
||||
return "t%d-%d" % (self.topological, self.stream)
|
||||
else:
|
||||
return "s%d" % (self.stream,)
|
||||
StreamToken.START = StreamToken.from_string("s0_0")
|
||||
|
||||
|
||||
class ThirdPartyInstanceID(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue