# 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 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 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 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.