Vizonex / Winloop

An Alternative library for uvloop compatability with windows
https://pypi.org/project/winloop
Apache License 2.0
74 stars 7 forks source link

Seemingly spurious UV_EOF (errno 4095) upon closing TCP connection. #12

Closed lschoe closed 6 months ago

lschoe commented 6 months ago

Hi, I've been testing Winloop and I was happy to see similar performance speedups on Windows as for uvloop on Linux. Really nice!

To get full functionality for my application I had to use two simple workarounds though, to fix two problems with Winloop 0.1.0.

The first problem happens upon closing a TCP connection. An error UV_EOF occurs on one side of the connection. The workaround is to simply ignore this exception. This error does not happen with any of the other event loops (asyncio's proactor, selector, nor with uvloop).

You can reproduce the problem running the simplest demo for the MPyC package. The following code is from the latest version MPyC v0.9.7 on GitHub, see mpyc/asyncoro.py. This is inside the connection_lost(exc) method:

          if 'winloop' in str(self.runtime._loop):
              # Workaround to suppress seemingly spurious UV_EOF (4095) exception from winloop.
              # For example, "python helloworld.py -M2 --output-file -E1"
              # creates a file "party2_1.log" with the error present.
              # Does not happen over SSL, which makes sense as for SSL
              # self.transport.can_write_eof() == False.
              if exc.errno == 4095:  # NB: exc is an OSError in Winloop 0.1.0
                  print(f'suppressed UV_EOF error in connection_lost(): {type(exc)=} {exc=}')
              else:
                  raise exc

Using python helloworld.py -M2 --output-file -E1 in mpyc/demos runs the demo between two parties on localhost. Party 0 experiences no problems, but party 1 will get the 4095 error upon closing the TCP connection. The file party2_1.log created will show the error in its last line. (Note that party 1 used a server listening for incoming connections from party 0, so party 0 acts as client and party 1 as server.)

The problem does not happen when using SSL, which makes sense as an SSL transport has can_write_eof() == False.

Do you have any idea what causes this problem?

For the other problem I'll open a separate issue.

Vizonex commented 6 months ago

I do not understand what causes this problem however if I could find a clean way to debug this issue that would be very helpful I guess a deep dive into how each handle behaves would allow me to find a way to solve this issue. There should be a built-in way to debug these modules since they came from uvloop originally...

lschoe commented 6 months ago

See the discussion for issue #13, for why the above workaround is no longer needed;)

You probably want to check the entire source code for similar cases. Maybe things like uv.ENOBUFS and uv.ECANCELED need to be handled similarly.