ouroboros-network icon indicating copy to clipboard operation
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

Open coot opened this issue 6 years ago • 4 comments
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

coot avatar Sep 06 '19 16:09 coot