kazu-yamamoto / quic

IETF QUIC library in Haskell
BSD 3-Clause "New" or "Revised" License
91 stars 13 forks source link

Deterministic state machine API #11

Open infinity0 opened 3 years ago

infinity0 commented 3 years ago

Hi, much of the current API is based on the IO monad. I wonder if it is possible to present a pure API instead, true to the Haskell spirit, that acts as a deterministic state machine?

https://github.com/quinn-rs/quinn is a rust QUIC library that implements the core protocol logic as a deterministic state machine, for example.

kazu-yamamoto commented 3 years ago

The current API is just IO only:

runQUICClient :: ClientConfig -> (Connection -> IO a) -> IO a 
stream :: Connection -> IO Stream 
closeStream :: Stream -> IO () 
recvStream :: Stream -> Int -> IO ByteString 
sendStream :: Stream -> ByteString -> IO () 
shutdownStream :: Stream -> IO () 

All other APIs are available from the Internal module. This is a network library, so I'm not so interested in pure stuff at this moment.

infinity0 commented 3 years ago

Thanks for the response. It looks like much of the Internal stuff is also in IO so it would not be possible to write a pure wrapper around it.

Writing a network library does not automatically have to involve IO, for example they are even doing it in Python for the benefits - https://sans-io.readthedocs.io/how-to-sans-io.html - in particular simplicity, testing and reuse.

I should also clarify that there are two major steps here - (1) converting the implementation to be entirely synchronous and nonblocking (2) dropping the IO monad. (1) is what is covered in the link above and is multi-language, (2) is specific to Haskell but is actually not so hard once (1) is done.

In particular, with asynchronous non-blocking code there is a temptation to use unbounded queues, of which there are many cases in this codebase. This effectively negates flowcontrol, as the consumer has no way to tell the producer to slow down, and the queue grows without bound by design. You might not notice any problems during most normal system loads, but it will cause problems during heavy load. I will file another issue for this.

kazu-yamamoto commented 3 years ago

Is sans-IO essentially event-driven programming based on pure data structures?

infinity0 commented 3 years ago

Pretty much, yes - another key point is the core protocol logic should be independent of any particular event-driver, so could be plugged into any.

kazu-yamamoto commented 3 years ago

@infinity0 Please find an e-mail message from me.