コード例 #1
0
    def __init__(self, hs: "HomeServer"):
        self.store = hs.get_datastore()
        self.server_name = hs.config.server_name
        self.clock = hs.get_clock()
        self.is_mine_id = hs.is_mine_id

        self.federation = None
        if hs.should_send_federation():
            self.federation = hs.get_federation_sender()

        if hs.config.worker.writers.typing != hs.get_instance_name():
            hs.get_federation_registry().register_instance_for_edu(
                "m.typing",
                hs.config.worker.writers.typing,
            )

        # map room IDs to serial numbers
        self._room_serials = {}  # type: Dict[str, int]
        # map room IDs to sets of users currently typing
        self._room_typing = {}  # type: Dict[str, Set[str]]

        self._member_last_federation_poke = {}  # type: Dict[RoomMember, int]
        self.wheel_timer = WheelTimer(bucket_size=5000)
        self._latest_room_serial = 0

        self.clock.looping_call(self._handle_timeouts, 5000)
コード例 #2
0
ファイル: typing.py プロジェクト: soumahorojean/synapse
    def __init__(self, hs):
        self.store = hs.get_datastore()
        self.server_name = hs.config.server_name
        self.auth = hs.get_auth()
        self.is_mine_id = hs.is_mine_id
        self.notifier = hs.get_notifier()
        self.state = hs.get_state_handler()

        self.hs = hs

        self.clock = hs.get_clock()
        self.wheel_timer = WheelTimer(bucket_size=5000)

        self.federation = hs.get_replication_layer()

        self.federation.register_edu_handler("m.typing", self._recv_edu)

        hs.get_distributor().observe("user_left_room", self.user_left_room)

        self._member_typing_until = {}  # clock time we expect to stop
        self._member_last_federation_poke = {}

        # map room IDs to serial numbers
        self._room_serials = {}
        self._latest_room_serial = 0
        # map room IDs to sets of users currently typing
        self._room_typing = {}

        self.clock.looping_call(
            self._handle_timeouts,
            5000,
        )
コード例 #3
0
    def __init__(self, hs):
        self.store = hs.get_datastore()
        self.server_name = hs.config.server_name
        self.auth = hs.get_auth()
        self.is_mine_id = hs.is_mine_id
        self.notifier = hs.get_notifier()
        self.state = hs.get_state_handler()

        self.hs = hs

        self.clock = hs.get_clock()
        self.wheel_timer = WheelTimer(bucket_size=5000)

        self.federation = hs.get_federation_sender()

        hs.get_federation_registry().register_edu_handler(
            "m.typing", self._recv_edu)

        hs.get_distributor().observe("user_left_room", self.user_left_room)

        self._member_typing_until = {}  # clock time we expect to stop
        self._member_last_federation_poke = {}

        self._latest_room_serial = 0
        self._reset()

        # caches which room_ids changed at which serials
        self._typing_stream_change_cache = StreamChangeCache(
            "TypingStreamChangeCache", self._latest_room_serial)

        self.clock.looping_call(self._handle_timeouts, 5000)
コード例 #4
0
ファイル: typing.py プロジェクト: samuelyi/synapse
    def __init__(self, hs: "HomeServer"):
        self.store = hs.get_datastores().main
        self._storage_controllers = hs.get_storage_controllers()
        self.server_name = hs.config.server.server_name
        self.clock = hs.get_clock()
        self.is_mine_id = hs.is_mine_id

        self.federation = None
        if hs.should_send_federation():
            self.federation = hs.get_federation_sender()

        if hs.get_instance_name() not in hs.config.worker.writers.typing:
            hs.get_federation_registry().register_instances_for_edu(
                EduTypes.TYPING,
                hs.config.worker.writers.typing,
            )

        # map room IDs to serial numbers
        self._room_serials: Dict[str, int] = {}
        # map room IDs to sets of users currently typing
        self._room_typing: Dict[str, Set[str]] = {}

        self._member_last_federation_poke: Dict[RoomMember, int] = {}
        self.wheel_timer: WheelTimer[RoomMember] = WheelTimer(bucket_size=5000)
        self._latest_room_serial = 0

        self.clock.looping_call(self._handle_timeouts, 5000)
コード例 #5
0
    def _reset(self) -> None:
        """Reset the typing handler's data caches."""
        # map room IDs to serial numbers
        self._room_serials = {}
        # map room IDs to sets of users currently typing
        self._room_typing = {}

        self._member_last_federation_poke = {}
        self.wheel_timer = WheelTimer(bucket_size=5000)
コード例 #6
0
    def test_single_insert_fetch(self):
        wheel = WheelTimer(bucket_size=5)

        obj = object()
        wheel.insert(100, obj, 150)

        self.assertListEqual(wheel.fetch(101), [])
        self.assertListEqual(wheel.fetch(110), [])
        self.assertListEqual(wheel.fetch(120), [])
        self.assertListEqual(wheel.fetch(130), [])
        self.assertListEqual(wheel.fetch(149), [])
        self.assertListEqual(wheel.fetch(156), [obj])
        self.assertListEqual(wheel.fetch(170), [])
コード例 #7
0
    def test_insert_past_multi(self):
        wheel = WheelTimer(bucket_size=5)

        obj1 = object()
        obj2 = object()
        obj3 = object()
        wheel.insert(100, obj1, 150)
        wheel.insert(100, obj2, 140)
        wheel.insert(100, obj3, 50)
        self.assertListEqual(wheel.fetch(110), [obj3])
        self.assertListEqual(wheel.fetch(120), [])
        self.assertListEqual(wheel.fetch(147), [obj2])
        self.assertListEqual(wheel.fetch(200), [obj1])
        self.assertListEqual(wheel.fetch(240), [])
コード例 #8
0
    def test_multi_insert(self):
        wheel = WheelTimer(bucket_size=5)

        obj1 = object()
        obj2 = object()
        obj3 = object()
        wheel.insert(100, obj1, 150)
        wheel.insert(105, obj2, 130)
        wheel.insert(106, obj3, 160)

        self.assertListEqual(wheel.fetch(110), [])
        self.assertListEqual(wheel.fetch(135), [obj2])
        self.assertListEqual(wheel.fetch(149), [])
        self.assertListEqual(wheel.fetch(158), [obj1])
        self.assertListEqual(wheel.fetch(160), [])
        self.assertListEqual(wheel.fetch(200), [obj3])
        self.assertListEqual(wheel.fetch(210), [])
コード例 #9
0
    def test_insert_past(self):
        wheel = WheelTimer(bucket_size=5)

        obj = object()
        wheel.insert(100, obj, 50)
        self.assertListEqual(wheel.fetch(120), [obj])
コード例 #10
0
ファイル: presence.py プロジェクト: xorob0/synapse
    def __init__(self, hs: "synapse.server.HomeServer"):
        super().__init__(hs)
        self.hs = hs
        self.is_mine_id = hs.is_mine_id
        self.server_name = hs.hostname
        self.wheel_timer = WheelTimer()
        self.notifier = hs.get_notifier()
        self.federation = hs.get_federation_sender()
        self.state = hs.get_state_handler()

        federation_registry = hs.get_federation_registry()

        federation_registry.register_edu_handler("m.presence", self.incoming_presence)

        LaterGauge(
            "synapse_handlers_presence_user_to_current_state_size",
            "",
            [],
            lambda: len(self.user_to_current_state),
        )

        now = self.clock.time_msec()
        for state in self.user_to_current_state.values():
            self.wheel_timer.insert(
                now=now, obj=state.user_id, then=state.last_active_ts + IDLE_TIMER
            )
            self.wheel_timer.insert(
                now=now,
                obj=state.user_id,
                then=state.last_user_sync_ts + SYNC_ONLINE_TIMEOUT,
            )
            if self.is_mine_id(state.user_id):
                self.wheel_timer.insert(
                    now=now,
                    obj=state.user_id,
                    then=state.last_federation_update_ts + FEDERATION_PING_INTERVAL,
                )
            else:
                self.wheel_timer.insert(
                    now=now,
                    obj=state.user_id,
                    then=state.last_federation_update_ts + FEDERATION_TIMEOUT,
                )

        # Set of users who have presence in the `user_to_current_state` that
        # have not yet been persisted
        self.unpersisted_users_changes = set()  # type: Set[str]

        hs.get_reactor().addSystemEventTrigger(
            "before",
            "shutdown",
            run_as_background_process,
            "presence.on_shutdown",
            self._on_shutdown,
        )

        self._next_serial = 1

        # Keeps track of the number of *ongoing* syncs on this process. While
        # this is non zero a user will never go offline.
        self.user_to_num_current_syncs = {}  # type: Dict[str, int]

        # Keeps track of the number of *ongoing* syncs on other processes.
        # While any sync is ongoing on another process the user will never
        # go offline.
        # Each process has a unique identifier and an update frequency. If
        # no update is received from that process within the update period then
        # we assume that all the sync requests on that process have stopped.
        # Stored as a dict from process_id to set of user_id, and a dict of
        # process_id to millisecond timestamp last updated.
        self.external_process_to_current_syncs = {}  # type: Dict[int, Set[str]]
        self.external_process_last_updated_ms = {}  # type: Dict[int, int]

        self.external_sync_linearizer = Linearizer(name="external_sync_linearizer")

        # Start a LoopingCall in 30s that fires every 5s.
        # The initial delay is to allow disconnected clients a chance to
        # reconnect before we treat them as offline.
        def run_timeout_handler():
            return run_as_background_process(
                "handle_presence_timeouts", self._handle_timeouts
            )

        self.clock.call_later(30, self.clock.looping_call, run_timeout_handler, 5000)

        def run_persister():
            return run_as_background_process(
                "persist_presence_changes", self._persist_unpersisted_changes
            )

        self.clock.call_later(60, self.clock.looping_call, run_persister, 60 * 1000)

        LaterGauge(
            "synapse_handlers_presence_wheel_timer_size",
            "",
            [],
            lambda: len(self.wheel_timer),
        )

        # Used to handle sending of presence to newly joined users/servers
        if hs.config.use_presence:
            self.notifier.add_replication_callback(self.notify_new_event)

        # Presence is best effort and quickly heals itself, so lets just always
        # stream from the current state when we restart.
        self._event_pos = self.store.get_current_events_token()
        self._event_processing = False
コード例 #11
0
ファイル: presence.py プロジェクト: zach-smith97/synapse
    def __init__(self, hs):
        """

        Args:
            hs (synapse.server.HomeServer):
        """
        self.hs = hs
        self.is_mine = hs.is_mine
        self.is_mine_id = hs.is_mine_id
        self.clock = hs.get_clock()
        self.store = hs.get_datastore()
        self.wheel_timer = WheelTimer()
        self.notifier = hs.get_notifier()
        self.federation = hs.get_federation_sender()
        self.state = hs.get_state_handler()

        federation_registry = hs.get_federation_registry()

        federation_registry.register_edu_handler(
            "m.presence", self.incoming_presence
        )
        federation_registry.register_edu_handler(
            "m.presence_invite",
            lambda origin, content: self.invite_presence(
                observed_user=UserID.from_string(content["observed_user"]),
                observer_user=UserID.from_string(content["observer_user"]),
            )
        )
        federation_registry.register_edu_handler(
            "m.presence_accept",
            lambda origin, content: self.accept_presence(
                observed_user=UserID.from_string(content["observed_user"]),
                observer_user=UserID.from_string(content["observer_user"]),
            )
        )
        federation_registry.register_edu_handler(
            "m.presence_deny",
            lambda origin, content: self.deny_presence(
                observed_user=UserID.from_string(content["observed_user"]),
                observer_user=UserID.from_string(content["observer_user"]),
            )
        )

        distributor = hs.get_distributor()
        distributor.observe("user_joined_room", self.user_joined_room)

        active_presence = self.store.take_presence_startup_info()

        # A dictionary of the current state of users. This is prefilled with
        # non-offline presence from the DB. We should fetch from the DB if
        # we can't find a users presence in here.
        self.user_to_current_state = {
            state.user_id: state
            for state in active_presence
        }

        LaterGauge(
            "synapse_handlers_presence_user_to_current_state_size", "", [],
            lambda: len(self.user_to_current_state)
        )

        now = self.clock.time_msec()
        for state in active_presence:
            self.wheel_timer.insert(
                now=now,
                obj=state.user_id,
                then=state.last_active_ts + IDLE_TIMER,
            )
            self.wheel_timer.insert(
                now=now,
                obj=state.user_id,
                then=state.last_user_sync_ts + SYNC_ONLINE_TIMEOUT,
            )
            if self.is_mine_id(state.user_id):
                self.wheel_timer.insert(
                    now=now,
                    obj=state.user_id,
                    then=state.last_federation_update_ts + FEDERATION_PING_INTERVAL,
                )
            else:
                self.wheel_timer.insert(
                    now=now,
                    obj=state.user_id,
                    then=state.last_federation_update_ts + FEDERATION_TIMEOUT,
                )

        # Set of users who have presence in the `user_to_current_state` that
        # have not yet been persisted
        self.unpersisted_users_changes = set()

        hs.get_reactor().addSystemEventTrigger("before", "shutdown", self._on_shutdown)

        self.serial_to_user = {}
        self._next_serial = 1

        # Keeps track of the number of *ongoing* syncs on this process. While
        # this is non zero a user will never go offline.
        self.user_to_num_current_syncs = {}

        # Keeps track of the number of *ongoing* syncs on other processes.
        # While any sync is ongoing on another process the user will never
        # go offline.
        # Each process has a unique identifier and an update frequency. If
        # no update is received from that process within the update period then
        # we assume that all the sync requests on that process have stopped.
        # Stored as a dict from process_id to set of user_id, and a dict of
        # process_id to millisecond timestamp last updated.
        self.external_process_to_current_syncs = {}
        self.external_process_last_updated_ms = {}
        self.external_sync_linearizer = Linearizer(name="external_sync_linearizer")

        # Start a LoopingCall in 30s that fires every 5s.
        # The initial delay is to allow disconnected clients a chance to
        # reconnect before we treat them as offline.
        self.clock.call_later(
            30,
            self.clock.looping_call,
            self._handle_timeouts,
            5000,
        )

        self.clock.call_later(
            60,
            self.clock.looping_call,
            self._persist_unpersisted_changes,
            60 * 1000,
        )

        LaterGauge("synapse_handlers_presence_wheel_timer_size", "", [],
                   lambda: len(self.wheel_timer))
コード例 #12
0
    def __init__(self, hs):
        super(PresenceHandler, self).__init__(hs)
        self.hs = hs
        self.clock = hs.get_clock()
        self.store = hs.get_datastore()
        self.wheel_timer = WheelTimer()
        self.notifier = hs.get_notifier()
        self.federation = hs.get_replication_layer()

        self.federation.register_edu_handler(
            "m.presence", self.incoming_presence
        )
        self.federation.register_edu_handler(
            "m.presence_invite",
            lambda origin, content: self.invite_presence(
                observed_user=UserID.from_string(content["observed_user"]),
                observer_user=UserID.from_string(content["observer_user"]),
            )
        )
        self.federation.register_edu_handler(
            "m.presence_accept",
            lambda origin, content: self.accept_presence(
                observed_user=UserID.from_string(content["observed_user"]),
                observer_user=UserID.from_string(content["observer_user"]),
            )
        )
        self.federation.register_edu_handler(
            "m.presence_deny",
            lambda origin, content: self.deny_presence(
                observed_user=UserID.from_string(content["observed_user"]),
                observer_user=UserID.from_string(content["observer_user"]),
            )
        )

        distributor = hs.get_distributor()
        distributor.observe("user_joined_room", self.user_joined_room)

        active_presence = self.store.take_presence_startup_info()

        # A dictionary of the current state of users. This is prefilled with
        # non-offline presence from the DB. We should fetch from the DB if
        # we can't find a users presence in here.
        self.user_to_current_state = {
            state.user_id: state
            for state in active_presence
        }

        metrics.register_callback(
            "user_to_current_state_size", lambda: len(self.user_to_current_state)
        )

        now = self.clock.time_msec()
        for state in active_presence:
            self.wheel_timer.insert(
                now=now,
                obj=state.user_id,
                then=state.last_active_ts + IDLE_TIMER,
            )
            self.wheel_timer.insert(
                now=now,
                obj=state.user_id,
                then=state.last_user_sync_ts + SYNC_ONLINE_TIMEOUT,
            )
            if self.hs.is_mine_id(state.user_id):
                self.wheel_timer.insert(
                    now=now,
                    obj=state.user_id,
                    then=state.last_federation_update_ts + FEDERATION_PING_INTERVAL,
                )
            else:
                self.wheel_timer.insert(
                    now=now,
                    obj=state.user_id,
                    then=state.last_federation_update_ts + FEDERATION_TIMEOUT,
                )

        # Set of users who have presence in the `user_to_current_state` that
        # have not yet been persisted
        self.unpersisted_users_changes = set()

        reactor.addSystemEventTrigger("before", "shutdown", self._on_shutdown)

        self.serial_to_user = {}
        self._next_serial = 1

        # Keeps track of the number of *ongoing* syncs. While this is non zero
        # a user will never go offline.
        self.user_to_num_current_syncs = {}

        # Start a LoopingCall in 30s that fires every 5s.
        # The initial delay is to allow disconnected clients a chance to
        # reconnect before we treat them as offline.
        self.clock.call_later(
            0 * 1000,
            self.clock.looping_call,
            self._handle_timeouts,
            5000,
        )

        metrics.register_callback("wheel_timer_size", lambda: len(self.wheel_timer))