def requeue_dead_letter(num_messages: int = 10, visibility_timeout: int = None) -> None: """ Re-queues everything in the Hedwig DLQ back into the Hedwig queue. :param num_messages: Maximum number of messages to fetch in one SQS call. Defaults to 10. :param visibility_timeout: The number of seconds the message should remain invisible to other queue readers. Defaults to None, which is queue default """ queue = get_queue(get_default_queue_name()) dead_letter_queue = get_dead_letter_queue(queue) logging.info("Re-queueing messages from {} to {}".format( dead_letter_queue.url, queue.url)) while True: queue_messages = get_queue_messages( dead_letter_queue, num_messages=num_messages, visibility_timeout=visibility_timeout, wait_timeout_s=1, ) if not queue_messages: break logging.info("got {} messages from dlq".format(len(queue_messages))) _enqueue_messages(queue, queue_messages) dead_letter_queue.delete_messages( Entries=[{ 'Id': message.message_id, 'ReceiptHandle': message.receipt_handle } for message in queue_messages]) logging.info("Re-queued {} messages".format(len(queue_messages)))
def test_listen_for_messages(self, mock_fetch_and_process, mock_get_queue): num_messages = 3 visibility_timeout_s = 4 loop_count = 1 listen_for_messages(num_messages, visibility_timeout_s, loop_count) queue_name = get_default_queue_name() mock_get_queue.assert_called_once_with(queue_name) mock_fetch_and_process.assert_called_once_with( queue_name, mock_get_queue.return_value, num_messages=num_messages, visibility_timeout=visibility_timeout_s)
def test_requeue_dead_letter_failure(mock_get_queue, mock_get_queue_messages): num_messages = 3 visibility_timeout = 4 messages = [mock.MagicMock() for _ in range(num_messages)] mock_get_queue_messages.side_effect = iter([messages, None]) dlq_name = f'{get_default_queue_name()}-DLQ' mock_queue, mock_dlq = mock.MagicMock(), mock.MagicMock() mock_queue.attributes = { 'RedrivePolicy': json.dumps({'deadLetterTargetArn': dlq_name}) } mock_queue.send_messages.return_value = { 'Failed': [{ 'Id': 'string' }], 'Successful': [] } mock_get_queue.side_effect = iter([mock_queue, mock_dlq]) with pytest.raises(PartialFailure) as exc_info: requeue_dead_letter(num_messages, visibility_timeout) assert exc_info.value.success_count == 0 assert exc_info.value.failure_count == 1 mock_get_queue.assert_has_calls([ mock.call(get_default_queue_name()), mock.call(dlq_name), ]) # not called a 2nd time after failure mock_get_queue_messages.assert_called_once_with( mock_dlq, num_messages=num_messages, visibility_timeout=visibility_timeout, wait_timeout_s=1, ) mock_queue.send_messages.assert_called_once_with( Entries=[{ 'Id': queue_message.message_id, 'MessageBody': queue_message.body, 'MessageAttributes': queue_message.message_attributes } for queue_message in messages]) mock_dlq.delete_messages.assert_not_called()
def extend_visibility_timeout(self, visibility_timeout_s: int) -> None: """ Extends visibility timeout of a message for long running tasks. """ from hedwig.consumer import get_default_queue_name queue_name = get_default_queue_name() client = _get_sqs_client() queue_url = _get_queue_url(client, queue_name) client.change_message_visibility( QueueUrl=queue_url, ReceiptHandle=self.receipt, VisibilityTimeout=visibility_timeout_s, )
def test_requeue_dead_letter(mock_get_queue, mock_get_queue_messages): num_messages = 3 visibility_timeout = 4 messages = [mock.MagicMock() for _ in range(num_messages)] mock_get_queue_messages.side_effect = iter([messages, None]) dlq_name = f'{get_default_queue_name()}-DLQ' mock_queue, mock_dlq = mock.MagicMock(), mock.MagicMock() mock_queue.attributes = {'RedrivePolicy': json.dumps({'deadLetterTargetArn': dlq_name})} mock_queue.send_messages.return_value = {'Failed': []} mock_get_queue.side_effect = iter([mock_queue, mock_dlq]) mock_dlq.delete_messages.return_value = {'Failed': []} requeue_dead_letter(num_messages, visibility_timeout) mock_get_queue.assert_has_calls([ mock.call(get_default_queue_name()), mock.call(dlq_name), ]) mock_get_queue_messages.assert_has_calls([ mock.call(mock_dlq, num_messages=num_messages, visibility_timeout=visibility_timeout, wait_timeout_s=1), mock.call(mock_dlq, num_messages=num_messages, visibility_timeout=visibility_timeout, wait_timeout_s=1), ]) mock_queue.send_messages.assert_called_once_with( Entries=[ { 'Id': queue_message.message_id, 'MessageBody': queue_message.body, 'MessageAttributes': queue_message.message_attributes } for queue_message in messages ] ) mock_dlq.delete_messages.assert_called_once_with( Entries=[ { 'Id': queue_message.message_id, 'ReceiptHandle': queue_message.receipt_handle, } for queue_message in messages ] )
def test_get_default_queue_name(): assert get_default_queue_name( ) == f'HEDWIG-{settings.HEDWIG_QUEUE.upper()}'