Pipelining is sending multiple requests over a socket and
receiving the responses later, in the same order. This is faster
than sending one request, waiting for the response, then sending
the next request, and so on. This implementation returns a
promise (future) response for each request that when invoked
waits for the response if not already arrived. Multiple threads
can send on the same pipeline (and get promises back); it will
pipeline each thread's request right away without waiting. A
pipeline closes itself when a read or write causes an error, so
you can detect a broken pipeline by checking isClosed. It also
closes itself when garbage collected, or you can close it
explicitly. Create new Pipeline on given connection. You should
close pipeline when finished, which will also close connection.
If pipeline is not closed but eventually garbage collected, it
will be closed along with connection. Send message to
destination; the destination must not response (otherwise future
calls will get these responses in