So here's the things to consider: | |
* Do not preallocate a read buffer per socket. | |
Either use polling or use a shared buffer pool. | |
* Avoid statefulnews, e.g: | |
- In windows, you can't use multiple completion ports with a handle. | |
- On unix, a socket is either in blocking or non-blocking mode | |
This creates problems when you want to share a handle with other processes | |
or between threads. For example, you might want to switch stdout to | |
non-blocking, but if stdout was inherited and shared with the parent | |
process, the parent process might not expect this and crash or malfunction. | |
For that reason, libuv implements separate code paths for shared handles, | |
which more than doubles the code size. | |
* Consider that not all protocols have TCP-like semantics. Consider: | |
- Some protocols (anything SOCK_SEQPACKET and also websockets and windows | |
named pipes in certain modes) are message-oriented. UDP packets are also | |
essentially messages. This needs to be a consideration when considering | |
the API. | |
- Some protocols do not support graceful close. TTY stdin might report an | |
EOF marker (zero size read) and yet more data follows after that. | |
Named pipes don't support graceful close at all. Unix FIFOs are half | |
duplex. | |
* For random access devices (files/block devices), avoid relying on the | |
operating for keeping track of the read position. This creates problems | |
when multiple threads are involved. E.g. when you offload the actual | |
file write to a thread pool, writes may happen in a different order than | |
in which they were submitted, which causes data corruption. | |
OS X had a bug for many years where the file position was entirely | |
un-thread-safe and files would get randomly corrupted in seemingly unrelated | |
locations. | |
Instead, prefer pread/pwrite for files. Windows has similar functionality. | |
* Consider that certain devices expect page-aligned buffers. Typically this | |
is true for block devices and files that are opened in unbufferd mode. | |
* Some third-party libraries (e.g. c-ares and libcurl) expect that you can do | |
unix-style poll/select on sockets for them. So you need to support this even | |
if you have a more efficient mode available for internal use. | |
(This is essentially the reason the wepoll strategy was developed). | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment