|
4 | 4 | This module provides low-level API for Tarantool
|
5 | 5 | '''
|
6 | 6 |
|
| 7 | +import time |
7 | 8 | import errno
|
| 9 | +import ctypes |
| 10 | +import ctypes.util |
8 | 11 | import socket
|
9 |
| -import time |
10 | 12 |
|
11 | 13 | from tarantool.response import Response
|
12 | 14 | from tarantool.request import (
|
@@ -77,6 +79,9 @@ def __init__(self, host, port,
|
77 | 79 | self._socket = None
|
78 | 80 | if connect_now:
|
79 | 81 | self.connect()
|
| 82 | + self._libc = ctypes.CDLL(ctypes.util.find_library('c'), use_errno=True) |
| 83 | + self._recv_type = ctypes.CFUNCTYPE(ctypes.c_ssize_t, *[ctypes.c_int, ctypes.c_void_p, ctypes.c_ssize_t, ctypes.c_int], use_errno=True) |
| 84 | + self._recv = self._recv_type(self._libc.recv) |
80 | 85 |
|
81 | 86 | def close(self):
|
82 | 87 | '''\
|
@@ -153,19 +158,16 @@ def _send_request_wo_reconnect(self, request, space_name = None, field_defs = No
|
153 | 158 |
|
154 | 159 | def _opt_reconnect(self):
|
155 | 160 | attempt = 0
|
| 161 | + if not self._socket: |
| 162 | + self.connect() |
156 | 163 | while True:
|
157 |
| - try: |
158 |
| - if not self._socket or not self._socket.recv(0, socket.MSG_DONTWAIT): |
159 |
| - time.sleep(self.reconnect_delay) |
160 |
| - self.connect() |
161 |
| - warn("Reconnect attempt %d of %d"%(attempt, self.reconnect_max_attempts), NetworkWarning) |
162 |
| - except socket.error as e: |
163 |
| - if e.errno == errno.EAGAIN: |
164 |
| - break |
165 |
| - else: |
166 |
| - time.sleep(self.reconnect_delay) |
167 |
| - self.connect() |
168 |
| - warn("%s : Reconnect attempt %d of %d"%(e.message, attempt, self.reconnect_max_attempts), NetworkWarning) |
| 164 | + rc = self._recv(self._socket.fileno(), '', 0, socket.MSG_DONTWAIT) |
| 165 | + if ctypes.get_errno() == errno.EAGAIN: |
| 166 | + ctypes.set_errno(0) |
| 167 | + break |
| 168 | + time.sleep(self.reconnect_delay) |
| 169 | + self.connect() |
| 170 | + warn("Reconnect attempt %d of %d"%(attempt, self.reconnect_max_attempts), NetworkWarning) |
169 | 171 | if attempt == self.reconnect_max_attempts:
|
170 | 172 | raise
|
171 | 173 | attempt += 1
|
|
0 commit comments