Exemple #1
0
    def wait_for_events(self, user, rooms, filter, timeout, callback):
        """Wait until the callback returns a non empty response or the
        timeout fires.
        """

        deferred = defer.Deferred()

        from_token = StreamToken("s0", "0", "0")

        listener = [
            _NotificationListener(
                user=user,
                rooms=rooms,
                from_token=from_token,
                limit=1,
                timeout=timeout,
                deferred=deferred,
            )
        ]

        if timeout:
            self._register_with_keys(listener[0])

        result = yield callback()
        timer = [None]

        if timeout:
            timed_out = [False]

            def _timeout_listener():
                timed_out[0] = True
                timer[0] = None
                listener[0].notify(self, [], from_token, from_token)

            # We create multiple notification listeners so we have to manage
            # canceling the timeout ourselves.
            timer[0] = self.clock.call_later(timeout / 1000.,
                                             _timeout_listener)

            while not result and not timed_out[0]:
                yield deferred
                deferred = defer.Deferred()
                listener[0] = _NotificationListener(
                    user=user,
                    rooms=rooms,
                    from_token=from_token,
                    limit=1,
                    timeout=timeout,
                    deferred=deferred,
                )
                self._register_with_keys(listener[0])
                result = yield callback()

        if timer[0] is not None:
            try:
                self.clock.cancel_call_later(timer[0])
            except:
                logger.exception("Failed to cancel notifer timer")

        defer.returnValue(result)
Exemple #2
0
 def get_current_token(self, direction='f'):
     token = StreamToken(
         room_key=(yield self.sources["room"].get_current_key(direction)),
         presence_key=(yield self.sources["presence"].get_current_key()),
         typing_key=(yield self.sources["typing"].get_current_key()),
         receipt_key=(yield self.sources["receipt"].get_current_key()),
     )
     defer.returnValue(token)
Exemple #3
0
    def _room_initial_sync_parted(self, user_id, room_id, pagin_config,
                                  membership, member_event_id, is_guest):
        room_state = yield self.store.get_state_for_events(
            [member_event_id], None
        )

        room_state = room_state[member_event_id]

        limit = pagin_config.limit if pagin_config else None
        if limit is None:
            limit = 10

        stream_token = yield self.store.get_stream_token_for_event(
            member_event_id
        )

        messages, token = yield self.store.get_recent_events_for_room(
            room_id,
            limit=limit,
            end_token=stream_token
        )

        messages = yield self._filter_events_for_client(
            user_id, messages, is_guest=is_guest
        )

        start_token = StreamToken(token[0], 0, 0, 0, 0)
        end_token = StreamToken(token[1], 0, 0, 0, 0)

        time_now = self.clock.time_msec()

        defer.returnValue({
            "membership": membership,
            "room_id": room_id,
            "messages": {
                "chunk": [serialize_event(m, time_now) for m in messages],
                "start": start_token.to_string(),
                "end": end_token.to_string(),
            },
            "state": [serialize_event(s, time_now) for s in room_state.values()],
            "presence": [],
            "receipts": [],
        })
Exemple #4
0
 def get_current_token(self):
     token = StreamToken(
         room_key=(
             yield self.sources["room"].get_current_key()
         ),
         presence_key=(
             yield self.sources["presence"].get_current_key()
         ),
         typing_key=(
             yield self.sources["typing"].get_current_key()
         )
     )
     defer.returnValue(token)
Exemple #5
0
    def get_current_token(self, direction='f'):
        push_rules_key, _ = self.store.get_push_rules_stream_token()

        token = StreamToken(
            room_key=(yield self.sources["room"].get_current_key(direction)),
            presence_key=(yield self.sources["presence"].get_current_key()),
            typing_key=(yield self.sources["typing"].get_current_key()),
            receipt_key=(yield self.sources["receipt"].get_current_key()),
            account_data_key=(yield
                              self.sources["account_data"].get_current_key()),
            push_rules_key=push_rules_key,
        )
        defer.returnValue(token)
Exemple #6
0
    def get_current_token_for_room(self, room_id):
        push_rules_key, _ = self.store.get_push_rules_stream_token()
        to_device_key = self.store.get_to_device_stream_token()

        token = StreamToken(
            room_key=(yield
                      self.sources["room"].get_current_key_for_room(room_id)),
            presence_key=(yield self.sources["presence"].get_current_key()),
            typing_key=(yield self.sources["typing"].get_current_key()),
            receipt_key=(yield self.sources["receipt"].get_current_key()),
            account_data_key=(yield
                              self.sources["account_data"].get_current_key()),
            push_rules_key=push_rules_key,
            to_device_key=to_device_key,
        )
        defer.returnValue(token)
Exemple #7
0
    def wait_for_events(self, user, rooms, filter, timeout, callback):
        """Wait until the callback returns a non empty response or the
        timeout fires.
        """

        deferred = defer.Deferred()

        from_token = StreamToken("s0", "0", "0")

        listener = [_NotificationListener(
            user=user,
            rooms=rooms,
            from_token=from_token,
            limit=1,
            timeout=timeout,
            deferred=deferred,
        )]

        if timeout:
            self._register_with_keys(listener[0])

        result = yield callback()
        if timeout:
            timed_out = [False]

            def _timeout_listener():
                timed_out[0] = True
                listener[0].notify(self, [], from_token, from_token)

            self.clock.call_later(timeout/1000., _timeout_listener)
            while not result and not timed_out[0]:
                yield deferred
                deferred = defer.Deferred()
                listener[0] = _NotificationListener(
                    user=user,
                    rooms=rooms,
                    from_token=from_token,
                    limit=1,
                    timeout=timeout,
                    deferred=deferred,
                )
                self._register_with_keys(listener[0])
                result = yield callback()

        defer.returnValue(result)
Exemple #8
0
    def get_current_token(self) -> StreamToken:
        push_rules_key = self.store.get_max_push_rules_stream_id()
        to_device_key = self.store.get_to_device_stream_token()
        device_list_key = self.store.get_device_stream_token()
        groups_key = self.store.get_group_stream_token()

        token = StreamToken(
            room_key=self.sources["room"].get_current_key(),
            presence_key=self.sources["presence"].get_current_key(),
            typing_key=self.sources["typing"].get_current_key(),
            receipt_key=self.sources["receipt"].get_current_key(),
            account_data_key=self.sources["account_data"].get_current_key(),
            push_rules_key=push_rules_key,
            to_device_key=to_device_key,
            device_list_key=device_list_key,
            groups_key=groups_key,
        )
        return token
Exemple #9
0
    def get_current_token(self) -> StreamToken:
        push_rules_key = self.store.get_max_push_rules_stream_id()
        to_device_key = self.store.get_to_device_stream_token()
        device_list_key = self.store.get_device_stream_token()

        token = StreamToken(
            room_key=self.sources.room.get_current_key(),
            presence_key=self.sources.presence.get_current_key(),
            typing_key=self.sources.typing.get_current_key(),
            receipt_key=self.sources.receipt.get_current_key(),
            account_data_key=self.sources.account_data.get_current_key(),
            push_rules_key=push_rules_key,
            to_device_key=to_device_key,
            device_list_key=device_list_key,
            # Groups key is unused.
            groups_key=0,
        )
        return token
Exemple #10
0
    def get_current_token_for_pagination(self):
        """Get the current token for a given room to be used to paginate
        events.

        The returned token does not have the current values for fields other
        than `room`, since they are not used during pagination.

        Returns:
            Deferred[StreamToken]
        """
        token = StreamToken(
            room_key=(yield self.sources["room"].get_current_key()),
            presence_key=0,
            typing_key=0,
            receipt_key=0,
            account_data_key=0,
            push_rules_key=0,
            to_device_key=0,
            device_list_key=0,
            groups_key=0,
        )
        return token
Exemple #11
0
    async def get_current_token_for_pagination(self,
                                               room_id: str) -> StreamToken:
        """Get the current token for a given room to be used to paginate
        events.

        The returned token does not have the current values for fields other
        than `room`, since they are not used during pagination.

        Returns:
            The current token for pagination.
        """
        token = StreamToken(
            room_key=await self.sources.room.get_current_key_for_room(room_id),
            presence_key=0,
            typing_key=0,
            receipt_key=0,
            account_data_key=0,
            push_rules_key=0,
            to_device_key=0,
            device_list_key=0,
            groups_key=0,
        )
        return token
Exemple #12
0
        def _get_recent_references_for_event_txn(
            txn: LoggingTransaction,
        ) -> Tuple[List[_RelatedEvent], Optional[StreamToken]]:
            txn.execute(sql, where_args + [limit + 1])

            last_topo_id = None
            last_stream_id = None
            events = []
            for row in txn:
                # Do not include edits for redacted events as they leak event
                # content.
                if not is_redacted or row[1] != RelationTypes.REPLACE:
                    events.append(_RelatedEvent(row[0], row[2]))
                last_topo_id = row[3]
                last_stream_id = row[4]

            # If there are more events, generate the next pagination key.
            next_token = None
            if len(events) > limit and last_topo_id and last_stream_id:
                next_key = RoomStreamToken(last_topo_id, last_stream_id)
                if from_token:
                    next_token = from_token.copy_and_replace(
                        StreamKeyType.ROOM, next_key)
                else:
                    next_token = StreamToken(
                        room_key=next_key,
                        presence_key=0,
                        typing_key=0,
                        receipt_key=0,
                        account_data_key=0,
                        push_rules_key=0,
                        to_device_key=0,
                        device_list_key=0,
                        groups_key=0,
                    )

            return events[:limit], next_token
Exemple #13
0
    def wait_for_events(self,
                        user,
                        rooms,
                        timeout,
                        callback,
                        from_token=StreamToken("s0", "0", "0")):
        """Wait until the callback returns a non empty response or the
        timeout fires.
        """
        user = str(user)
        user_stream = self.user_to_user_stream.get(user)
        if user_stream is None:
            appservice = yield self.store.get_app_service_by_user_id(user)
            current_token = yield self.event_sources.get_current_token()
            rooms = yield self.store.get_rooms_for_user(user)
            rooms = [room.room_id for room in rooms]
            user_stream = _NotifierUserStream(
                user=user,
                rooms=rooms,
                appservice=appservice,
                current_token=current_token,
                time_now_ms=self.clock.time_msec(),
            )
            self._register_with_keys(user_stream)

        result = None
        if timeout:
            # Will be set to a _NotificationListener that we'll be waiting on.
            # Allows us to cancel it.
            listener = None

            def timed_out():
                if listener:
                    listener.deferred.cancel()

            timer = self.clock.call_later(timeout / 1000., timed_out)

            prev_token = from_token
            while not result:
                try:
                    current_token = user_stream.current_token

                    result = yield callback(prev_token, current_token)
                    if result:
                        break

                    # Now we wait for the _NotifierUserStream to be told there
                    # is a new token.
                    # We need to supply the token we supplied to callback so
                    # that we don't miss any current_token updates.
                    prev_token = current_token
                    listener = user_stream.new_listener(prev_token)
                    yield listener.deferred
                except defer.CancelledError:
                    break

            self.clock.cancel_call_later(timer, ignore_errs=True)
        else:
            current_token = user_stream.current_token
            result = yield callback(from_token, current_token)

        defer.returnValue(result)