~ubuntu-branches/ubuntu/trusty/python-eventlet/trusty-proposed

« back to all changes in this revision

Viewing changes to debian/patches/retry-on-timeout.patch

  • Committer: Package Import Robot
  • Author(s): Dave Walker (Daviey)
  • Date: 2012-05-18 13:36:26 UTC
  • mfrom: (4.1.4 sid)
  • Revision ID: package-import@ubuntu.com-20120518133626-v2hvgj9cza44ub0r
Tags: 0.9.16-2ubuntu1
* Merge from Debian, remaining changes:
  - Drop python-zmq from build depends, it's currently in universe.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
Description: If an operation times out, try one last time.
2
 
 This addresses a problem where a timeout fires even though the
3
 
 connection was actually correctly established.
4
 
Origin: Chris Behrens, https://bitbucket-assetroot.s3.amazonaws.com/which_linden/eventlet/20110601/87/eventlet-socket-timeout.diff
5
 
Bug: https://bitbucket.org/which_linden/eventlet/issue/87/socket-connects-are-incorrectly-reported
6
 
Bug-Ubuntu: https://launchpad.net/bugs/771512
7
 
Reviewed-By: Soren Hansen <soren@ubuntu.com>
8
 
Last-Update: 2011-06-01
9
 
 
10
 
--- a/eventlet/greenio.py
11
 
+++ b/eventlet/greenio.py
12
 
@@ -174,8 +174,16 @@
13
 
                     return
14
 
                 if time.time() >= end:
15
 
                     raise socket.timeout("timed out")
16
 
-                trampoline(fd, write=True, timeout=end-time.time(),
17
 
-                        timeout_exc=socket.timeout("timed out"))
18
 
+                try:
19
 
+                    trampoline(fd, write=True, timeout=end-time.time(),
20
 
+                            timeout_exc=socket.timeout("timed out"))
21
 
+                except socket.timeout, e:
22
 
+                    try:
23
 
+                        if socket_connect(fd, address):
24
 
+                            return
25
 
+                        raise e
26
 
+                    except:
27
 
+                        raise e
28
 
                 socket_checkerr(fd)
29
 
 
30
 
     def connect_ex(self, address):
31
 
@@ -197,8 +205,16 @@
32
 
                         return 0
33
 
                     if time.time() >= end:
34
 
                         raise socket.timeout(errno.EAGAIN)
35
 
-                    trampoline(fd, write=True, timeout=end-time.time(),
36
 
-                            timeout_exc=socket.timeout(errno.EAGAIN))
37
 
+                    try:
38
 
+                        trampoline(fd, write=True, timeout=end-time.time(),
39
 
+                                timeout_exc=socket.timeout(errno.EAGAIN))
40
 
+                    except socket.timeout, e:
41
 
+                        try:
42
 
+                            if socket_connect(fd, address):
43
 
+                                return
44
 
+                            raise e
45
 
+                        except:
46
 
+                            raise e
47
 
                     socket_checkerr(fd)
48
 
                 except socket.error, ex:
49
 
                     return get_errno(ex)
50
 
@@ -218,42 +234,43 @@
51
 
             "makefile instead", DeprecationWarning, stacklevel=2)
52
 
         return self.makefile(*args, **kw)
53
 
 
54
 
-    def recv(self, buflen, flags=0):
55
 
-        fd = self.fd
56
 
+    def _read_io(self, fd, f, *args, **kwargs):
57
 
         if self.act_non_blocking:
58
 
-            return fd.recv(buflen, flags)
59
 
+            return f(*args, **kwargs)
60
 
         while True:
61
 
             try:
62
 
-                return fd.recv(buflen, flags)
63
 
+                return f(*args, **kwargs)
64
 
             except socket.error, e:
65
 
                 if get_errno(e) in SOCKET_BLOCKING:
66
 
                     pass
67
 
-                elif get_errno(e) in SOCKET_CLOSED:
68
 
+                # XXX -- Why does recv() do this?
69
 
+                elif f == fd.recv and get_errno(e) in SOCKET_CLOSED:
70
 
                     return ''
71
 
                 else:
72
 
                     raise
73
 
-            trampoline(fd, 
74
 
-                read=True, 
75
 
-                timeout=self.gettimeout(), 
76
 
-                timeout_exc=socket.timeout("timed out"))
77
 
+            try:
78
 
+                trampoline(fd, 
79
 
+                        read=True, 
80
 
+                        timeout=self.gettimeout(), 
81
 
+                        timeout_exc=socket.timeout("timed out"))
82
 
+            except socket.timeout, e:
83
 
+                # Try one last time to see if the timeout is 'real'
84
 
+                try:
85
 
+                    return f(*args, **kwargs)
86
 
+                except:
87
 
+                    raise e
88
 
+
89
 
+    def recv(self, buflen, flags=0):
90
 
+        return self._read_io(self.fd, self.fd.recv, buflen, flags)
91
 
 
92
 
     def recvfrom(self, *args):
93
 
-        if not self.act_non_blocking:
94
 
-            trampoline(self.fd, read=True, timeout=self.gettimeout(),
95
 
-                    timeout_exc=socket.timeout("timed out"))
96
 
-        return self.fd.recvfrom(*args)
97
 
+        return self._read_io(self.fd, self.fd.recvfrom, *args)
98
 
 
99
 
     def recvfrom_into(self, *args):
100
 
-        if not self.act_non_blocking:
101
 
-            trampoline(self.fd, read=True, timeout=self.gettimeout(),
102
 
-                    timeout_exc=socket.timeout("timed out"))
103
 
-        return self.fd.recvfrom_into(*args)
104
 
+        return self._read_io(self.fd, self.fd.recvfrom_into, *args)
105
 
 
106
 
     def recv_into(self, *args):
107
 
-        if not self.act_non_blocking:
108
 
-            trampoline(self.fd, read=True, timeout=self.gettimeout(),
109
 
-                    timeout_exc=socket.timeout("timed out"))
110
 
-        return self.fd.recv_into(*args)
111
 
+        return self._read_io(self.fd, self.fd.recv_into, *args)
112
 
 
113
 
     def send(self, data, flags=0):
114
 
         fd = self.fd
115
 
@@ -264,7 +281,7 @@
116
 
         total_sent = 0
117
 
         len_data = len(data)
118
 
 
119
 
-        while 1:
120
 
+        while True:
121
 
             try:
122
 
                 total_sent += fd.send(data[total_sent:], flags)
123
 
             except socket.error, e:
124
 
@@ -274,8 +291,15 @@
125
 
             if total_sent == len_data:
126
 
                 break
127
 
 
128
 
-            trampoline(self.fd, write=True, timeout=self.gettimeout(),
129
 
-                    timeout_exc=socket.timeout("timed out"))
130
 
+            try:
131
 
+                trampoline(fd, write=True, timeout=self.gettimeout(),
132
 
+                        timeout_exc=socket.timeout("timed out"))
133
 
+            except socket.timeout, e:
134
 
+                # Try one last time to see if the timeout is 'real'
135
 
+                try:
136
 
+                    total_sent += fd.send(data[total_sent:], flags)
137
 
+                except:
138
 
+                    raise e
139
 
 
140
 
         return total_sent
141
 
 
142
 
@@ -286,8 +310,26 @@
143
 
             tail += self.send(data[tail:], flags)
144
 
 
145
 
     def sendto(self, *args):
146
 
-        trampoline(self.fd, write=True)
147
 
-        return self.fd.sendto(*args)
148
 
+        fd = self.fd
149
 
+        if self.act_non_blocking:
150
 
+            return fd.sendto(*args)
151
 
+        while True:
152
 
+            try:
153
 
+                return fd.sendto(*args)
154
 
+            except socket.error, e:
155
 
+                if get_errno(e) in SOCKET_BLOCKING:
156
 
+                    pass
157
 
+                else:
158
 
+                    raise
159
 
+            try:
160
 
+                trampoline(fd, write=True, timeout=self.gettimeout(),
161
 
+                        timeout_exc=socket.timeout("timed out"))
162
 
+            except socket.timeout, e:
163
 
+                # Try one last time to see if the timeout is 'real'
164
 
+                try:
165
 
+                    return fd.sendto(*args)
166
 
+                except:
167
 
+                    raise e
168
 
 
169
 
     def setblocking(self, flag):
170
 
         if flag:
171
 
--- a/tests/greenio_test.py
172
 
+++ b/tests/greenio_test.py
173
 
@@ -133,7 +133,8 @@
174
 
             self.assertEqual(e.args[0], 'timed out')
175
 
 
176
 
     def test_recvfrom_into_timeout(self):
177
 
-        buf = buffer(array.array('B'))
178
 
+        buf = array.array('B')
179
 
+        buf.fromstring('\0')
180
 
 
181
 
         gs = greenio.GreenSocket(
182
 
             socket.socket(socket.AF_INET, socket.SOCK_DGRAM))
183
 
@@ -148,7 +149,8 @@
184
 
             self.assertEqual(e.args[0], 'timed out')
185
 
 
186
 
     def test_recv_into_timeout(self):
187
 
-        buf = buffer(array.array('B'))
188
 
+        buf = array.array('B')
189
 
+        buf.fromstring('\0')
190
 
 
191
 
         listener = greenio.GreenSocket(socket.socket())
192
 
         listener.bind(('', 0))