new implementation of sync-producer-async-consumer
This fixes the handling of promises (e.g. requests) that resolve out-of-order. The sync-producer-async-consumer has been defined as the Pipe
abstraction, and an implementation has been written using an async loop that uses Lwt.pick
across three concurrent tasks.
Tests have been added that verify two scenarios are handled as expected: promises resolving out-of-order are handled in order of resolution, and async handling of promises does not block on an empty channel between the producer and consumer.