Skip to content

Commit e24e977

Browse files
committed
Merge branch 'pr/1108' into pythonparser
2 parents 2f3afb0 + a8bf82f commit e24e977

File tree

2 files changed

+131
-3
lines changed

2 files changed

+131
-3
lines changed

redis/connection.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,7 @@ def on_connect(self, connection):
276276

277277
def on_disconnect(self):
278278
"Called when the socket disconnects"
279-
if self._sock is not None:
280-
self._sock.close()
281-
self._sock = None
279+
self._sock = None
282280
if self._buffer is not None:
283281
self._buffer.close()
284282
self._buffer = None

tests/test_multiprocessing.py

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import pytest
2+
import multiprocessing
3+
import contextlib
4+
5+
from redis.connection import Connection, ConnectionPool
6+
from redis.exceptions import ConnectionError
7+
8+
9+
@contextlib.contextmanager
10+
def exit_callback(callback, *args):
11+
try:
12+
yield
13+
finally:
14+
callback(*args)
15+
16+
17+
class TestMultiprocessing(object):
18+
# Test connection sharing between forks.
19+
# See issue #1085 for details.
20+
21+
def test_connection(self):
22+
conn = Connection()
23+
assert conn.send_command('ping') is None
24+
assert conn.read_response() == b'PONG'
25+
26+
def target(conn):
27+
assert conn.send_command('ping') is None
28+
assert conn.read_response() == b'PONG'
29+
conn.disconnect()
30+
31+
proc = multiprocessing.Process(target=target, args=(conn,))
32+
proc.start()
33+
proc.join(3)
34+
assert proc.exitcode is 0
35+
36+
# Check that connection is still alive after fork process has exited.
37+
with pytest.raises(ConnectionError):
38+
assert conn.send_command('ping') is None
39+
assert conn.read_response() == b'PONG'
40+
41+
def test_close_connection_in_main(self):
42+
conn = Connection()
43+
assert conn.send_command('ping') is None
44+
assert conn.read_response() == b'PONG'
45+
46+
def target(conn, ev):
47+
ev.wait()
48+
assert conn.send_command('ping') is None
49+
assert conn.read_response() == b'PONG'
50+
51+
ev = multiprocessing.Event()
52+
proc = multiprocessing.Process(target=target, args=(conn, ev))
53+
proc.start()
54+
55+
conn.disconnect()
56+
ev.set()
57+
58+
proc.join(3)
59+
assert proc.exitcode is 1
60+
61+
@pytest.mark.parametrize('max_connections', [1, 2, None])
62+
def test_pool(self, max_connections):
63+
pool = ConnectionPool.from_url('redis://localhost',
64+
max_connections=max_connections)
65+
66+
conn = pool.get_connection('ping')
67+
with exit_callback(pool.release, conn):
68+
assert conn.send_command('ping') is None
69+
assert conn.read_response() == b'PONG'
70+
71+
def target(pool):
72+
with exit_callback(pool.disconnect):
73+
conn = pool.get_connection('ping')
74+
with exit_callback(pool.release, conn):
75+
assert conn.send_command('ping') is None
76+
assert conn.read_response() == b'PONG'
77+
78+
proc = multiprocessing.Process(target=target, args=(pool,))
79+
proc.start()
80+
proc.join(3)
81+
assert proc.exitcode is 0
82+
83+
# Check that connection is still alive after fork process has exited.
84+
conn = pool.get_connection('ping')
85+
with exit_callback(pool.release, conn):
86+
with pytest.raises(ConnectionError):
87+
assert conn.send_command('ping') is None
88+
assert conn.read_response() == b'PONG'
89+
90+
@pytest.mark.parametrize('max_connections', [1, 2, None])
91+
def test_close_pool_in_main(self, max_connections):
92+
pool = ConnectionPool.from_url('redis://localhost',
93+
max_connections=max_connections)
94+
95+
conn = pool.get_connection('ping')
96+
assert conn.send_command('ping') is None
97+
assert conn.read_response() == b'PONG'
98+
99+
def target(pool, disconnect_event):
100+
conn = pool.get_connection('ping')
101+
with exit_callback(pool.release, conn):
102+
assert conn.send_command('ping') is None
103+
assert conn.read_response() == b'PONG'
104+
disconnect_event.wait()
105+
assert conn.send_command('ping') is None
106+
assert conn.read_response() == b'PONG'
107+
108+
ev = multiprocessing.Event()
109+
110+
proc = multiprocessing.Process(target=target, args=(pool, ev))
111+
proc.start()
112+
113+
pool.disconnect()
114+
ev.set()
115+
proc.join(3)
116+
assert proc.exitcode is 0
117+
118+
def test_redis(self, r):
119+
assert r.ping() is True
120+
121+
def target(redis):
122+
assert redis.ping() is True
123+
del redis
124+
125+
proc = multiprocessing.Process(target=target, args=(r,))
126+
proc.start()
127+
proc.join(3)
128+
assert proc.exitcode is 0
129+
130+
assert r.ping() is True

0 commit comments

Comments
 (0)