Issue2374
Created on 2015-07-01.23:56:28 by mbakht, last changed 2015-11-23.21:10:18 by zyasoft.
Messages | |||
---|---|---|---|
msg10136 (view) | Author: Mehedi (mbakht) | Date: 2015-07-02.00:00:40 | |
When a call is made from jython (2.7.0) code for connecting to RabbitMQ through pika.BlockingConnection, it results in the following error: _socket.error: [Errno 92] Protocol not available The call to pika.BlockingConnection ends up calling the following block of code in pika (https://github.com/pika/pika/blob/master/pika/adapters/base_connection.py#L195) def _create_and_connect_to_socket(self, sock_addr_tuple): """Create socket and connect to it, using SSL if enabled. :returns: error string on failure; None on success """ self.socket = socket.socket(sock_addr_tuple[0], socket.SOCK_STREAM, 0) The last value passed in socket.socket(..) denotes the protocol number which is 0 in this case. This code calls the socket method in jython's _socket.py (https://github.com/jythontools/jython/blob/master/Lib/_socket.py#L1456): def socket(family=None, type=None, proto=None): return _socketobject(family, type, proto) Since the python code made the call with proto value set to 0, that is the value that will be passed here to _socketobject. Now, here is the code in _socketobject (https://github.com/jythontools/jython/blob/master/Lib/_socket.py#L1308): class _socketobject(object): __doc__ = _realsocket.__doc__ def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None): if _sock is None: _sock = _realsocket(family, type, proto) proto still has the value 0 as it gets passed down to realsocket. class _realsocket(object): def __init__(self, family=None, type=None, proto=None): # FIXME verify args are correct self.family = family self.type = type if proto is None: if type == SOCK_STREAM: proto = IPPROTO_TCP elif type == SOCK_DGRAM: proto = IPPROTO_UDP self.proto = proto Since proto is not None, it does not get assigned the default value of TCP. This zero value eventually causes the "Protocol not available" error. |
|||
msg10144 (view) | Author: Jim Baker (zyasoft) | Date: 2015-07-06.20:59:28 | |
Same problem as #2273 |
|||
msg10194 (view) | Author: Erich Heine (sophacles) | Date: 2015-09-01.19:35:19 | |
This bug is affecting me as well, so I did some more digging - It turns out there are a couple of problems here... (which maybe are getting conflated somehow?) In the constructor of socket, CPython doesn't allow None for proto. It requires an integer. In setsockopt after creating a socket with proto = 0. The pika module mentioned sets TCP_NODELAY after creating a socket with proto = 0. In CPython this works, but in jython it does not. Here is the output of a Jython session (note the bare value 6 is the value on my system for socket.SOL_TCP which is not defined in Jython a third incompatibility) >>> import socket >>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, None) >>> s.setsockopt(6, socket.TCP_NODELAY, 1) >>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) >>> s.setsockopt(6, socket.TCP_NODELAY, 1) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/Cellar/jython/2.7.0/libexec/Lib/_socket.py", line 1367, in meth return getattr(self._sock,name)(*args) File "/usr/local/Cellar/jython/2.7.0/libexec/Lib/_socket.py", line 357, in handle_exception return method_or_function(*args, **kwargs) File "/usr/local/Cellar/jython/2.7.0/libexec/Lib/_socket.py", line 357, in handle_exception return method_or_function(*args, **kwargs) File "/usr/local/Cellar/jython/2.7.0/libexec/Lib/_socket.py", line 1204, in setsockopt raise error(errno.ENOPROTOOPT, "Protocol not available") _socket.error: [Errno 42] Protocol not available In CPython this is the output: >>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, None) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/Cellar/python/2.7.7_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 187, in __init__ _sock = _realsocket(family, type, proto) TypeError: an integer is required >>> >>> >>> s = socket.socket(socekt.AF_INET, socket.SOCK_STREAM, 0) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'socekt' is not defined >>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) >>> s.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1) Note that in both systems, creating the socket without passing a value to the 3rd argument of the socket constructor, setsockopt works just fine. The mismatch appears to be on explicitly setting the 3rd argument to the default value. |
|||
msg10195 (view) | Author: Jim Baker (zyasoft) | Date: 2015-09-01.20:37:57 | |
Erich, thanks for your detailed analysis. This is very helpful! I'm still planning on getting this work completed in 2.7.1. Note that beta 1 is scheduled for Sept 10, however we should have enough time by Oct 8 to see this in beta 2. |
|||
msg10224 (view) | Author: Jim Baker (zyasoft) | Date: 2015-09-04.04:44:21 | |
Fixed as of https://hg.python.org/jython/rev/b3b82ef080a9 |
|||
msg10500 (view) | Author: Jim Baker (zyasoft) | Date: 2015-11-23.21:10:18 | |
One thing we missed is the lack of socket.SOL_TCP (see msg10194). Opened a new bug for this, #2436 |
History | |||
---|---|---|---|
Date | User | Action | Args |
2015-11-23 21:10:18 | zyasoft | set | messages: + msg10500 |
2015-09-17 20:31:29 | zyasoft | set | status: pending -> closed |
2015-09-04 04:44:21 | zyasoft | set | status: open -> pending resolution: fixed messages: + msg10224 |
2015-09-01 20:37:58 | zyasoft | set | messages: + msg10195 |
2015-09-01 19:35:20 | sophacles | set | nosy:
+ sophacles messages: + msg10194 |
2015-07-28 15:07:03 | zyasoft | set | assignee: zyasoft |
2015-07-06 20:59:28 | zyasoft | set | nosy:
+ zyasoft messages: + msg10144 milestone: Jython 2.7.1 |
2015-07-02 00:00:40 | mbakht | set | messages:
+ msg10136 severity: normal -> urgent |
2015-07-01 23:56:28 | mbakht | create |
Supported by Python Software Foundation,
Powered by Roundup