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:
Patrick Cloke 2023-01-25 16:34:37 -05:00 committed by GitHub
parent 3c3ba31507
commit 7e8d455280
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 19 additions and 11 deletions

1
changelog.d/14880.bugfix Normal file
View file

@ -0,0 +1 @@
Fix a bug when using the `send_local_online_presence_to` module API.

View file

@ -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.

View file

@ -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(

View file

@ -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:

View file

@ -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]: