-
Notifications
You must be signed in to change notification settings - Fork 876
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Fix Windows non-blocking I/O #1555
Conversation
Created based on discussion here: jackc#1525 (review) Fixes jackc#1552
…id that channel leaked in case when `SetBlockingMode` will return error
It seems unfortunate for the concept of non-blocking mode to leak out of nbconn into the higher layers (e.g. the copy protocol support). Would it be possible for this logic to be internal? I think that the only methods that could be affected from the outside are |
…ilBlock` operations
@jackc I have updated the PR according to you comment. Please check it again.
UPD: I decided to use atomic counter to determine should socket be set to blocking or non-blocking mode, but it might not work on some CPUs or in some circumstances. Do you have any thoughts on this? |
32 bit atomic should work on any CPU, anyway you can use atomic.Int32. |
@drakkan thanks for the tip, I've updated PR |
This logic is tricky and there's a few cases I am concerned about. What if If
I suspect that the whole It's possible that neither of these cases actually will occur based on how and where |
@jackc I see your point, I've updated PR to use mutex instead of atomic |
@codercms even with this patch applied some test cases hang as you also noticed
take a look here
and
Deadlines don't seem to work, this may be the root cause. @jackc maybe better suggest to use v4 on windows until this is fixed (I guess it might take some time) |
@jackc @drakkan I've added some deadline simulation, please have a look on it
|
It looks good, thanks! If test cases cover all possible usages we should be fine now. The only failing test case is To be honest, I'm not happy with all this platform-specific, complicated and hard-to-maintain code (in general, not only related to this PR), it can hide subtle and hard-to-diagnose bugs (e.g. the remaining failed test case) |
@drakkan I agree, that platform specific code isn't a good approach, but unfortunately GoLang's stdlib doesn't have non-blocking I/O for Windows. It's actually normal practice in C/C++ world to have platform specific code, especially for sockets, because Windows sockets API is different from sockets API in UNIX (and behavior is different too). Projects like cURL, nginx, boost.asio (async I/O library for C++), libuv (event loop and non-blocking I/O library, used in Node.js) have different network layer implementation for Windows. UNIX-like systems have advanced socket polling mechanisms like kqueue, epoll, but Windows doesn't have kqueue nor epoll, it has WaitForMultipleObjects. |
First of all I appreciate a lot your efforts. |
@drakkan for sure we can use just goroutines and simulate non-blocking I/O, but see this comment - #1525 (comment)
|
I think this is in a mergeable state. But I don't plan on tagging a new release for a while, I think it would be good to let the more adventurous people who run master give us some more real world testing.
You and me both. I wrote almost all of nbconn except for this new Windows support and I totally agree it is very complicated and tricky. Unfortunately, I have been unable to find a better way. (TLS support greatly complicates it as well. )
There were a few reasons for introducing non-blocking IO. One was to be able to efficiently test if a connection was live before sending a query. If a connection has been closed on the server end it is sometimes still possible to write to the connection. The connection closed error is not received until the connection is read from. This causes a problem where is is impossible to say if a insert/update/delete statement actually was executed. By testing the connection first this occurrence can be minimized. In addition, the CopyFrom logic is much simpler with non-blocking I/O. |
@jackc thanks for the detailed explanation. I updated SFTPGo to use the latest version and I did several tests on a Windows VM. It works fine for me but SFTPGo is not a database intesive application. @codercms thanks for your work! |
Created based on discussion here: #1525 (review)
Fixes #1552