Re-work QueueingConsumer shutdown and cancellation semantics

When we encounter a cancellation signal, we enqueue and subsequently
throw its exception, however we then throw it away such that consumers
can come and go without affecting the QueueingConsumer object itself.

On encountering a shutdown signal, we push it onto the (tail of the)
queue and keep it there, re-queueing it each time #nextDelivery() is
called.