tailhook / rotor

The mio-based framework for rust for doing I/O in simple and composable way (ABANDONED)
MIT License
360 stars 25 forks source link

Response structure doesn't permit correct use of edge polling #13

Closed reem closed 8 years ago

reem commented 8 years ago

Each state machine is only allowed to respond to a read/write hint with a single Response, this is in some ways fundamentally incompatible with the way edge polling is meant to work.

For instance, take the case of a TcpAcceptor registered with edge polling and listening for readable events. Assume our state machine has two variants, Acceptor(TcpAcceptor) and Connection(TcpConnection). When we receive a read hint on this acceptor, we must accept in a loop until we receive a WouldBlock error. By the time we get WouldBlock we may have accepted many new connections; however, we are only allowed to spawn one new state machine from each hint.

tailhook commented 8 years ago

I think the accept thing is the only case where you might reach this issue, and it works by processing following responses in Machine::spawned handler.

Initial accept: https://github.com/tailhook/rotor-stream/blob/v0.4.0/src/accept.rs#L49 Continuation: https://github.com/tailhook/rotor-stream/blob/v0.4.0/src/accept.rs#L74 (edit: fixed second link)

Rotor guarantees to continue calling Machine::spawned until that returns ok or done.

This is done for two reasons:

  1. Avoid memory allocations on the critical path
  2. Good error handling: it would be hard to handle errors if response contains list of new machines

BTW, I recommend using rotor_stream::Accept instead of reinventing the wheel.

tailhook commented 8 years ago

Does it work for you? Any issues left unsolved?

reem commented 8 years ago

Yeah, this solution does work, but I am still lightly concerned about the code duplication between the ready and spawn methods.