Пример #1
0
    async def _send_resend_request(self, missing_seq_nums: List[int]):
        # Wait for opportunity to send resend request. Must:
        #
        #   1.) Have waited for resend requests from the target; and
        #   2.) Not be busy handling a resend request from the target

        if not self.waited_for_resend_request_event.is_set():
            wait_time = self.startup_time + timedelta(
                seconds=SeqNumManagerApp.RESEND_WAIT_TIME
            )
            wait_time = max(wait_time.timestamp() - datetime.utcnow().timestamp(), 0)
            logger.info(
                f"{self.name}: Waiting {wait_time:0.2f}s for ResendRequests from target "
                f"before doing gap fill..."
            )

            await asyncio.sleep(wait_time)
            self.waited_for_resend_request_event.set()

        # Don't send our own resend requests if we are busy handling one received from the target
        await self.resend_request_handled_event.wait()

        # Separate task
        asyncio.create_task(
            self.send(
                admin.ResendRequestMessage(missing_seq_nums[0], missing_seq_nums[-1])
            )
        )
Пример #2
0
    async def test_handle_resend_request_sends_resend_request(
        self, pipeline_with_messages
    ):
        seq_num_app = SeqNumManagerApp(pipeline_with_messages)
        seq_num_app.send_seq_num = 3  # 3 messages sent so far
        resend_begin_seq_num = 2  # Simulate resend request of 2 and 3

        await seq_num_app._handle_resend_request(
            admin.ResendRequestMessage(resend_begin_seq_num)
        )

        # Wait for separate 'send' tasks to complete
        tasks = asyncio.all_tasks()
        await asyncio.wait(tasks, timeout=0.1)

        assert pipeline_with_messages.send.call_count == 2

        for idx in range(pipeline_with_messages.send.call_count):
            message = pipeline_with_messages.send.mock_calls[idx][1][0]
            # Check sequence number
            assert message.seq_num == resend_begin_seq_num + idx
            # Check PossDup flag
            assert bool(message.PossDupFlag) is True
            # Check sending time
            assert str(message.OrigSendingTime) == str(message.SendingTime)
Пример #3
0
    async def test_handle_resend_request_converts_admin_messages_to_sequence_reset_messages(
        self, logon_message, pipeline_with_messages, messages
    ):
        seq_num_app = SeqNumManagerApp(pipeline_with_messages)

        admin_messages = [logon_message, HeartbeatMessage("test123")]

        # Inject admin messages
        messages = admin_messages + messages

        # Reset sequence numbers
        for idx, message in enumerate(messages):
            message.MsgSeqNum = idx + 1

        message_store_app = pipeline_with_messages.apps[MessageStoreApp.name]
        await message_store_app.initialize()
        message_store_app.store._store.clear()

        for message in messages:
            await message_store_app.set_sent(message)

        seq_num_app.send_seq_num = max(
            message.seq_num
            for message in pipeline_with_messages.apps[
                MessageStoreApp.name
            ].store._store.values()
        )

        resend_begin_seq_num = 1

        await seq_num_app._handle_resend_request(
            admin.ResendRequestMessage(resend_begin_seq_num)
        )

        # Wait for separate 'send' tasks to complete
        tasks = asyncio.all_tasks()
        await asyncio.wait(tasks, timeout=0.1)

        assert pipeline_with_messages.send.call_count == 6

        admin_messages_resend = pipeline_with_messages.send.mock_calls[0][1][0]
        # Check SequenceReset message is constructed correctly
        assert admin_messages_resend.seq_num == 1
        assert int(admin_messages_resend.NewSeqNo) == 3
        assert bool(admin_messages_resend.PossDupFlag) is True

        # Check first non-admin message starts with correct sequence number
        first_non_admin_message_resend = pipeline_with_messages.send.mock_calls[1][1][0]
        assert first_non_admin_message_resend.seq_num == 3