Scheduling freezes on large number of delayed messages
eubelov opened this issue · 1 comments
eubelov commented
Setup: CAP 8.1 RabbitMq + Postgres
Given: A large number of delayed messages (>20000 in my case)
When IDataStorage.ScheduleMessagesOfDelayedAsync
fetches all messages from the DB and schedules them for processing, entire operation is executed inside a DB transaction and with FOR UPDATE SKIP LOCKED
instruction that locks all selected rows for the duration of the transaction.
Next, the following happens:
- Transaction (T1) starts in
ScheduleMessagesOfDelayedAsync
- Pending messages are read and enqueued via
_dispatcher.EnqueueToScheduler()
(IProcessor.Delayed.cs) - Messages are added to the
_schedulerQueue
priority queue for async processing by a background task. (Dispatcher.cs) - The BG task picks the next available message from the priority queue:
_schedulerQueue.TryPeek(out _, out _nextSendTime)
- The message is sent to transport (
await _sender.SendAsync(_schedulerQueue.Dequeue());
) andSetSuccessfulState
is called (IMessageSender.Default.cs) - An update statement is executed in
ChangeMessageStateAsync()
(IDataStorage.PostgreSql.cs) against the DB while the T1 transaction is still not committed. Thus, the update statement times out and fails as the affected row is still locked by T1. - The
while (_schedulerQueue.TryPeek(out _, out _nextSendTime))
loop freezes forever. (IDispatcher.Default.cs)
yang-xiaodong commented