Files
DataPath/plan.txt
T
Michael Fabian 'Xaymar' Dirks d6e6ec96c4 windows: Rewrite onto IOCompletionPorts
IOCompletionPorts are the modern way to handle asynchronous IO without affected the system too much. Synchronization, work allocation and spreading, etc is all handled by the OS for us, which reduces the work we have to do in order to be NUMA aware. While this is far from perfect, it should perform better than a naive threaded approach.

ToDo:
- Add documentation generation
- Add Github Actions integration
- Write tests for everything.
- Update 'benchmark' sample to work again.
- Figure out a useful way to deal with connect/disconnect/error events.
- Figure out the broken pipe error, caused by an additional connected event where none should have been.
2020-06-22 00:43:06 +02:00

103 lines
3.5 KiB
Plaintext

# Implementations
## Windows
Client/Server Socket:
- Constant reads on a thread?
- Solves the needs to queue up reads.
- Adds slight overhead and complexity.
- Doesn't work when there is no callback for reading.
- Not really the most optimal solution
- Can writes be happening in parallel?
- In that case clients would benefit from IOCP with no limit.
- Otherwise go with a queue approach (further reduces delay)
- Allow queueing reads? (can't have more than one read at at time)
- Allow multiple parallel writes?
- Read & Write async?
Client Socket:
- IOCP with <Hardware Concurrency> Threads, or limit to 2?
- Hardware Concurrency is only useful when more than one write is happening (but that may not work anyway, needs testing
- Async connect or sync connect?
- Former is modern and expected.
Server & Socket:
- IOCP with <Hardware Concurrency> Threads, shared with Sockets
- Connect on Server
- Without callback, defaults to instantly disconnect clients.
- Callback overrides that behavior.
- Should socket status be in Socket or Server? Or both?
- If in server or both, some sort of callback to the server has to be done.
- If only in socket, server still needs to track the backlog of sockets.
- Socket calls back into server on disconnect to update status?
# Structures
```
Task {
Events {
completed(bytes, void* data)
}
static Task* create();
}
```
Basics:
- Server-Client-Model, One to Many connection (one Server may have any number of Clients)
- Everything is asynchronous, nothing should be synchronous to reduce CPU locks.
- Multiplatform (Linux, Mac, Windows, Android?, iOS?)
- Only handles data, there is no code for RPC.
Reading and Writing:
- These will return an object that is an asynchronous request, which may complete immediately or in the near future.
- Main code will only keep a soft reference, and the user will be holding the hard reference.
- Losing the hard reference means ignoring this request and simply using the next one, if there is one. If not, then different behavior is invoked depending on the task:
- If a read succeeded but the hard reference to the actual task was lost, store it temporarily for the next read call.
- If a write was being calculated, but hard reference is lost, we abort right there and continue with the next one.
- Windows: Writing to the socket does not require any synchronization, reading however does due to the varying packet sizes and the need for a header.
Server:
- Can accept new connections (callback with bool return value?)
- Can not connect by itself, can only accept connections.
- Can't read or write data without a connection.
- Doesn't care who or what is connected.
Client/Handler:
- Can disconnect.
- Can read and write data.
- Can't reconnect.
Client:
- Can connect.
Task Model:
- read, write and accept all return "tasks".
- Tasks can be cancelled, waited on and the result can be used later.
- Read, Write use IOTasks.
- Accept uses AcceptTask.
- Due to the asynchronous model, no data is kept around on the socket or server if possible. All associated data with the task is lost on dereferencing it.
- THIS WONT WORK if the task is killed while the OS is using it - it will cause segfaults. Need another solution!
IOTask (Windows)
- OVERLAPPED
- std::vector<char> data (buffer containing read/write data)
- completed() returns status (Success, Unknown or Failure).
- data() returns the data std::vector.
- wait() for waiting endlessly.
- wait_for() for waiting for a specific amount of time.
- wait_until() for waiting until a specific moment in time.