kazu-yamamoto / quic

IETF QUIC library in Haskell
BSD 3-Clause "New" or "Revised" License
91 stars 13 forks source link

Many uses of unbounded queues (TQueue) #12

Open infinity0 opened 3 years ago

infinity0 commented 3 years ago

There are many uses of TQueue in this codebase, which is an unbounded queue. This effectively negates flow-control, as the consumer has no way to tell the producer to slow down, and the queue grows without bound by design.

You might not notice any problems during most normal system loads, but it can cause hard-to-debug problems during heavy load - the scheduler generally cannot figure out which consumers need to be run more often than which producers to keep the queue sizes down and so the queues may run out of memory.

The solution is not simple; generally one ought to replace the queue with a bounded queue, but depending on the relationship between the producers and consumers setting the appropriate bound is not obvious and case-dependent. If it is set too low, deadlocks can occur, e.g. if two threads have two queues between them in opposite directions, this is a cyclic relationship and can deadlock depending precisely on how the production / consumption depend on each other.

infinity0 commented 3 years ago

A nonblocking implementation as described in https://github.com/kazu-yamamoto/quic/issues/11#issuecomment-732995227 avoids this entirely, since it does not need to use blocking queues.