ouroboros-network
ouroboros-network copied to clipboard
TypeProtocol: add an operation which allows to either await for piplined requests or await for another event to send more data
trafficstars
In block fetch:
-- We have no requests to send. Check if we have any pending pipelined
-- results to collect. If so, go round and collect any more. If not, block
-- and wait for some new requests.
senderIdle (Succ outstanding) =
SenderCollect (Just (senderAwait (Succ outstanding)))
(\_ -> senderIdle outstanding)
We could benefit if the driver would allow us to decide to block until, either of one of events:
- new message has arrived
- we have a new request to do
Now we have only SenderCollect primitive:
SenderCollect :: Maybe (PeerSender ps pr (st :: ps) (S n) c m a)
-> (c -> PeerSender ps pr (st :: ps) n c m a)
-> PeerSender ps pr (st :: ps) (S n) c m a
which only allows to peek if a response has arrived and then either send more or collect a response. The problem with block fetch is that we might be awaiting to get more requests to send.
We could add
SenderCheck
:: (STM m c -> PeerSender ps pr (st :: ps) n c m a)
-> PeerSender ps pr (st :: ps) n c m a
as a constructor. The STM m c would allow to await for values in the response queue, and we could use orElse to combine it with some other STM transaction:
SenderCheck $ \ awaitQueue -> SenderEffect $ do
r <- atomically $ (Left <$> awaitQueue) `orElse` (Right <$> awaitForMoreRequests)
case r of
Left _ -> -- we can collect the response
Right _ -> -- we have more requests to send