forked from MirrorHub/synapse
Fix a bug in the send_local_online_presence_to module API (#14880)
Destination was being used incorrectly (a single destination instead of a list of destinations was being passed). This also updates some of the types in the area to not use Collection[str], which is a footgun.
This commit is contained in:
parent
3c3ba31507
commit
7e8d455280
5 changed files with 19 additions and 11 deletions
1
changelog.d/14880.bugfix
Normal file
1
changelog.d/14880.bugfix
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Fix a bug when using the `send_local_online_presence_to` module API.
|
|
@ -64,7 +64,13 @@ from synapse.replication.tcp.commands import ClearUserSyncsCommand
|
||||||
from synapse.replication.tcp.streams import PresenceFederationStream, PresenceStream
|
from synapse.replication.tcp.streams import PresenceFederationStream, PresenceStream
|
||||||
from synapse.storage.databases.main import DataStore
|
from synapse.storage.databases.main import DataStore
|
||||||
from synapse.streams import EventSource
|
from synapse.streams import EventSource
|
||||||
from synapse.types import JsonDict, StreamKeyType, UserID, get_domain_from_id
|
from synapse.types import (
|
||||||
|
JsonDict,
|
||||||
|
StrCollection,
|
||||||
|
StreamKeyType,
|
||||||
|
UserID,
|
||||||
|
get_domain_from_id,
|
||||||
|
)
|
||||||
from synapse.util.async_helpers import Linearizer
|
from synapse.util.async_helpers import Linearizer
|
||||||
from synapse.util.metrics import Measure
|
from synapse.util.metrics import Measure
|
||||||
from synapse.util.wheel_timer import WheelTimer
|
from synapse.util.wheel_timer import WheelTimer
|
||||||
|
@ -320,7 +326,7 @@ class BasePresenceHandler(abc.ABC):
|
||||||
for destination, host_states in hosts_to_states.items():
|
for destination, host_states in hosts_to_states.items():
|
||||||
self._federation.send_presence_to_destinations(host_states, [destination])
|
self._federation.send_presence_to_destinations(host_states, [destination])
|
||||||
|
|
||||||
async def send_full_presence_to_users(self, user_ids: Collection[str]) -> None:
|
async def send_full_presence_to_users(self, user_ids: StrCollection) -> None:
|
||||||
"""
|
"""
|
||||||
Adds to the list of users who should receive a full snapshot of presence
|
Adds to the list of users who should receive a full snapshot of presence
|
||||||
upon their next sync. Note that this only works for local users.
|
upon their next sync. Note that this only works for local users.
|
||||||
|
@ -1601,7 +1607,7 @@ class PresenceEventSource(EventSource[int, UserPresenceState]):
|
||||||
# Having a default limit doesn't match the EventSource API, but some
|
# Having a default limit doesn't match the EventSource API, but some
|
||||||
# callers do not provide it. It is unused in this class.
|
# callers do not provide it. It is unused in this class.
|
||||||
limit: int = 0,
|
limit: int = 0,
|
||||||
room_ids: Optional[Collection[str]] = None,
|
room_ids: Optional[StrCollection] = None,
|
||||||
is_guest: bool = False,
|
is_guest: bool = False,
|
||||||
explicit_room_id: Optional[str] = None,
|
explicit_room_id: Optional[str] = None,
|
||||||
include_offline: bool = True,
|
include_offline: bool = True,
|
||||||
|
@ -1688,7 +1694,7 @@ class PresenceEventSource(EventSource[int, UserPresenceState]):
|
||||||
|
|
||||||
# The set of users that we're interested in and that have had a presence update.
|
# The set of users that we're interested in and that have had a presence update.
|
||||||
# We'll actually pull the presence updates for these users at the end.
|
# We'll actually pull the presence updates for these users at the end.
|
||||||
interested_and_updated_users: Collection[str]
|
interested_and_updated_users: StrCollection
|
||||||
|
|
||||||
if from_key is not None:
|
if from_key is not None:
|
||||||
# First get all users that have had a presence update
|
# First get all users that have had a presence update
|
||||||
|
@ -2120,7 +2126,7 @@ class PresenceFederationQueue:
|
||||||
# stream_id, destinations, user_ids)`. We don't store the full states
|
# stream_id, destinations, user_ids)`. We don't store the full states
|
||||||
# for efficiency, and remote workers will already have the full states
|
# for efficiency, and remote workers will already have the full states
|
||||||
# cached.
|
# cached.
|
||||||
self._queue: List[Tuple[int, int, Collection[str], Set[str]]] = []
|
self._queue: List[Tuple[int, int, StrCollection, Set[str]]] = []
|
||||||
|
|
||||||
self._next_id = 1
|
self._next_id = 1
|
||||||
|
|
||||||
|
@ -2142,7 +2148,7 @@ class PresenceFederationQueue:
|
||||||
self._queue = self._queue[index:]
|
self._queue = self._queue[index:]
|
||||||
|
|
||||||
def send_presence_to_destinations(
|
def send_presence_to_destinations(
|
||||||
self, states: Collection[UserPresenceState], destinations: Collection[str]
|
self, states: Collection[UserPresenceState], destinations: StrCollection
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Send the presence states to the given destinations.
|
"""Send the presence states to the given destinations.
|
||||||
|
|
||||||
|
|
|
@ -1158,7 +1158,7 @@ class ModuleApi:
|
||||||
# Send to remote destinations.
|
# Send to remote destinations.
|
||||||
destination = UserID.from_string(user).domain
|
destination = UserID.from_string(user).domain
|
||||||
presence_handler.get_federation_queue().send_presence_to_destinations(
|
presence_handler.get_federation_queue().send_presence_to_destinations(
|
||||||
presence_events, destination
|
presence_events, [destination]
|
||||||
)
|
)
|
||||||
|
|
||||||
def looping_background_call(
|
def looping_background_call(
|
||||||
|
|
|
@ -46,6 +46,7 @@ from synapse.types import (
|
||||||
JsonDict,
|
JsonDict,
|
||||||
PersistedEventPosition,
|
PersistedEventPosition,
|
||||||
RoomStreamToken,
|
RoomStreamToken,
|
||||||
|
StrCollection,
|
||||||
StreamKeyType,
|
StreamKeyType,
|
||||||
StreamToken,
|
StreamToken,
|
||||||
UserID,
|
UserID,
|
||||||
|
@ -716,7 +717,7 @@ class Notifier:
|
||||||
|
|
||||||
async def _get_room_ids(
|
async def _get_room_ids(
|
||||||
self, user: UserID, explicit_room_id: Optional[str]
|
self, user: UserID, explicit_room_id: Optional[str]
|
||||||
) -> Tuple[Collection[str], bool]:
|
) -> Tuple[StrCollection, bool]:
|
||||||
joined_room_ids = await self.store.get_rooms_for_user(user.to_string())
|
joined_room_ids = await self.store.get_rooms_for_user(user.to_string())
|
||||||
if explicit_room_id:
|
if explicit_room_id:
|
||||||
if explicit_room_id in joined_room_ids:
|
if explicit_room_id in joined_room_ids:
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from typing import Collection, Generic, List, Optional, Tuple, TypeVar
|
from typing import Generic, List, Optional, Tuple, TypeVar
|
||||||
|
|
||||||
from synapse.types import UserID
|
from synapse.types import StrCollection, UserID
|
||||||
|
|
||||||
# The key, this is either a stream token or int.
|
# The key, this is either a stream token or int.
|
||||||
K = TypeVar("K")
|
K = TypeVar("K")
|
||||||
|
@ -28,7 +28,7 @@ class EventSource(Generic[K, R]):
|
||||||
user: UserID,
|
user: UserID,
|
||||||
from_key: K,
|
from_key: K,
|
||||||
limit: int,
|
limit: int,
|
||||||
room_ids: Collection[str],
|
room_ids: StrCollection,
|
||||||
is_guest: bool,
|
is_guest: bool,
|
||||||
explicit_room_id: Optional[str] = None,
|
explicit_room_id: Optional[str] = None,
|
||||||
) -> Tuple[List[R], K]:
|
) -> Tuple[List[R], K]:
|
||||||
|
|
Loading…
Reference in a new issue