Open KodrAus opened 8 years ago
The right level of abstraction needs to be worked out for this. libuv
already providing streaming abstractions we can hook into, so they seem like a good base to target.
I also want to support the scenario where we have machines that have no socket attached. So maybe we can have something like:
IMachine =
member this.create ...
member this.wakeup ...
member this.timeout ...
IStream =
member this.idle ...
member this.read ...
member this.write ...
member this.hup ...
EDIT: I'm going with the same kind of abstraction as rotor
, where there's a standard Socket<'m, 'c>
fsm that implements IMachine<'c>
where 'm
is an object that implements ISocketMachine<'c>
that contains user-logic.
It'll call the members described in IStream
above.
The socket design needs to be seamless with the lower machine API, and take advantage of what libuv
offers.
How these two concepts play together is a tricky question. Maybe we need to have a general scope and a stream scope, that has other stuff on it. The main thing to figure out is where the stream handles belong; it's not really a thing machines should be managing, but it shouldn't really leak into the loop more than necessary.
It also shouldn't be possible to mess with stream concepts from a machine that doesn't have them. Machines with sockets should be added in the same way though.
This is the meat and potatoes. Implementation is going to be very tricky, because it's outside the .NET Happy Path™.
There is a lot of stuff in Kestrel already that can be pinched, starting with the memory pool (or looking into System.Buffers
). The difference is that Kestrel translates libuv
's evented api into a poll (or pull) based api that's more standard for .NET. I'm not really trying to build this kind of abstraction so don't need to worry so much about it.
Buffering may come into consideration in the socket
fsm to prevent calls to machines with really small payloads. Chunked io is probably a bad idea fullstop.
Some useful points of reference from Kestrel:
A simple sample for using libuv
for an echo server:
https://github.com/bodokaiser/libuv-snippets/blob/master/tcp-echo-server/tcp_echo_server.c
For #1
Use a
uv_tcp
to bind a socket to a machine that executes events on theready
method in the machine.