Introduce ChannelOutboundQueue

This patch introduces a tunable queue for outstanding requests. The core
idea is to maintain a limited queue between the message produces and the
IO threads. The producers place their pre-made messages to the queue,
where the IO thread picks them up and pushes them down the pipeline.
Should the queue be empty, the caller is informed of this fact and can
choose a recovery strategy -- current implementation reports
RejectedExecutionException.

The flush task is placed in the IO pool only when the channel is
writable and the queue is non-empty. A single run of the flush task is
time-limited, so a single channel which is being churned by producer
does not end up monopolizing a particular thread for extended periods of
time -- after a tunable time the flush task will re-insert itself on the
task queue and exit.

Change-Id: If6f09c60cf2cf5a69e9f051e2dfe2bae3bb90b5d
Signed-off-by: Robert Varga <rovarga@cisco.com>