gevent
gevent copied to clipboard
Resoult of select.select was wrong when monkey patched with loop 'libuv'
- gevent version: 21.1.2 from PyPI
- Python version: cPython 3.8.8 embed downloaded from python.org
- Operating System: Windows 7 SP1 64bit
Description:
I use select.select to observe readable status, once after received some data, then select.select still return readable even no data can be readed.
No tracebacks, it just blocked the code. I has wrote some test code use assert, you will run and see the traceback:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
What I've run:
- first run a echo server
Python 3.10.1 (tags/v3.10.1:2cd268a, Dec 6 2021, 19:10:37) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import select, socket
>>> s_addr = ('127.0.0.1', 9999)
>>>
>>> s_tcp = socket.socket()
>>> s_udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> s_tcp.bind(s_addr)
>>> s_udp.bind(s_addr)
>>> s_tcp.listen(2)
>>>
>>> while 1:
... ss = select.select([s_tcp, s_udp], [], [], 1)[0]
... if ss:
... s = ss[0]
... if s is s_tcp:
... s = s.accept()[0]
... s.send(s.recv(1024))
... else:
... s.sendto(*s.recvfrom(1024))
...
- gevent monkey patch with loop 'libuv-cffi' is failed
Python 3.10.1 (tags/v3.10.1:2cd268a, Dec 6 2021, 19:10:37) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.environ['GEVENT_LOOP'] = 'libuv-cffi'
>>> import gevent.monkey
>>> gevent.monkey.patch_all()
True
>>> import select, socket
>>> s_addr = ('127.0.0.1', 9999)
>>> d_test = b'test'
>>>
>>> # TCP
>>> s_tcp = socket.socket()
>>> s_tcp.connect(s_addr)
>>> assert any(select.select([s_tcp], [], [], 1)) == False
>>> assert s_tcp.send(d_test) == len(d_test)
>>> assert any(select.select([s_tcp], [], [], 1)) == True
>>> assert s_tcp.recv(len(d_test)) == d_test
>>> assert any(select.select([s_tcp], [], [], 1)) == False
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
>>>
>>> # UDP
>>> s_udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> assert any(select.select([s_udp], [], [], 1)) == False
>>> assert s_udp.sendto(d_test, s_addr) == len(d_test)
>>> assert any(select.select([s_udp], [], [], 1)) == True
>>> assert s_udp.recvfrom(len(d_test)) == (d_test, s_addr)
>>> assert any(select.select([s_udp], [], [], 1)) == False
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
>>>
- gevent monkey patch with loop 'libev-cext' is OK
Python 3.10.1 (tags/v3.10.1:2cd268a, Dec 6 2021, 19:10:37) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.environ['GEVENT_LOOP'] = 'libev-cext'
>>> import gevent.monkey
>>> gevent.monkey.patch_all()
True
>>> import select, socket
>>> s_addr = ('127.0.0.1', 9999)
>>> d_test = b'test'
>>>
>>> # TCP
>>> s_tcp = socket.socket()
>>> s_tcp.connect(s_addr)
>>> assert any(select.select([s_tcp], [], [], 1)) == False
>>> assert s_tcp.send(d_test) == len(d_test)
>>> assert any(select.select([s_tcp], [], [], 1)) == True
>>> assert s_tcp.recv(len(d_test)) == d_test
>>> assert any(select.select([s_tcp], [], [], 1)) == False
>>>
>>> # UDP
>>> s_udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> assert any(select.select([s_udp], [], [], 1)) == False
>>> assert s_udp.sendto(d_test, s_addr) == len(d_test)
>>> assert any(select.select([s_udp], [], [], 1)) == True
>>> assert s_udp.recvfrom(len(d_test)) == (d_test, s_addr)
>>> assert any(select.select([s_udp], [], [], 1)) == False
>>>
- no gevent monkey patch is OK
Python 3.10.1 (tags/v3.10.1:2cd268a, Dec 6 2021, 19:10:37) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import select, socket
>>> s_addr = ('127.0.0.1', 9999)
>>> d_test = b'test'
>>>
>>> # TCP
>>> s_tcp = socket.socket()
>>> s_tcp.connect(s_addr)
>>> assert any(select.select([s_tcp], [], [], 1)) == False
>>> assert s_tcp.send(d_test) == len(d_test)
>>> assert any(select.select([s_tcp], [], [], 1)) == True
>>> assert s_tcp.recv(len(d_test)) == d_test
>>> assert any(select.select([s_tcp], [], [], 1)) == False
>>>
>>> # UDP
>>> s_udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> assert any(select.select([s_udp], [], [], 1)) == False
>>> assert s_udp.sendto(d_test, s_addr) == len(d_test)
>>> assert any(select.select([s_udp], [], [], 1)) == True
>>> assert s_udp.recvfrom(len(d_test)) == (d_test, s_addr)
>>> assert any(select.select([s_udp], [], [], 1)) == False
>>>
@jamadden A year has passed, do you have any idea? And I have re-wrote the test codes, make it more clear.