Pull to refresh

Гарантировано переложить события из БД в RabbitMq streams на .net

Нужно реализовать transaction-outbox, только без дебезиума. Казалось бы ничего сложного: в цикле читаем сообщения из бд и отправляем в стрим. Если успех, удаляем сообщение из бд. Если была ошибка, берём таймаут и начинаем всё заново.

Проблема в том, что в библиотеке RabbitMQ Stream .Net Client отправка сообщения и получение результата отправки никак не связаны между собой. Не смотря на то, что список сообщений отправляется синхронно через метод Send, результат отправки можно получить только внутри коллбэк-функции ConfirmationHandler, а значит у нас трудности.

Что делать?

Решение 1: пробрасывать через метод отправки некий контекст, например добавлять к каждому сообщению ид строки из бд и удалять строку внутриConfirmationHandler. Может сработать, но оказалось, что все свойства класса Message сериализуются и уходят в стрим, а значит будет мусор. К тому же возникают сложности с управлением транзакцией, потому что непонятно когда будет удаление и требуются дополнительные синхронизации.

Решение 2: использовать TaskCompletionSource. Перед отправкой создаём новый экземпляр TaskCompletionSource, потом ожидаем результата в надежде, что библиотека отработает как надо и количество вызовов ConfirmationHandler будет совпадать с количеством вызовов Send.

Картинка, потому что лимит по символам
Картинка, потому что лимит по символам

Такое решение работает, но всё же выглядит хрупким.

Решение 3: Использовать более низкоуровневые api библиотеки, но кажется, что уйдёт куча времени на обвязку с неясным выхлопом.

Tags:
Total votes 1: ↑1 and ↓0+3
Comments2

Articles