summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy McCurdy <andy@andymccurdy.com>2019-01-28 13:37:55 -0800
committerAndy McCurdy <andy@andymccurdy.com>2019-01-28 13:37:55 -0800
commite24e9770eb9e27453b52c433366cd8a033640cb4 (patch)
treee5dcf882b7e4f45c6b6903b55d96b28914179aed
parent2f3afb0a2b6adaa7287173f07ea5b7fee8551083 (diff)
parenta8bf82fc9edc0040062e5b3ee4c3074f67caaea1 (diff)
downloadredis-py-e24e9770eb9e27453b52c433366cd8a033640cb4.tar.gz
Merge branch 'pr/1108' into pythonparser
-rwxr-xr-xredis/connection.py4
-rw-r--r--tests/test_multiprocessing.py130
2 files changed, 131 insertions, 3 deletions
diff --git a/redis/connection.py b/redis/connection.py
index 0d1c394..c81e4c1 100755
--- a/redis/connection.py
+++ b/redis/connection.py
@@ -276,9 +276,7 @@ class PythonParser(BaseParser):
def on_disconnect(self):
"Called when the socket disconnects"
- if self._sock is not None:
- self._sock.close()
- self._sock = None
+ self._sock = None
if self._buffer is not None:
self._buffer.close()
self._buffer = None
diff --git a/tests/test_multiprocessing.py b/tests/test_multiprocessing.py
new file mode 100644
index 0000000..dae35bc
--- /dev/null
+++ b/tests/test_multiprocessing.py
@@ -0,0 +1,130 @@
+import pytest
+import multiprocessing
+import contextlib
+
+from redis.connection import Connection, ConnectionPool
+from redis.exceptions import ConnectionError
+
+
+@contextlib.contextmanager
+def exit_callback(callback, *args):
+ try:
+ yield
+ finally:
+ callback(*args)
+
+
+class TestMultiprocessing(object):
+ # Test connection sharing between forks.
+ # See issue #1085 for details.
+
+ def test_connection(self):
+ conn = Connection()
+ assert conn.send_command('ping') is None
+ assert conn.read_response() == b'PONG'
+
+ def target(conn):
+ assert conn.send_command('ping') is None
+ assert conn.read_response() == b'PONG'
+ conn.disconnect()
+
+ proc = multiprocessing.Process(target=target, args=(conn,))
+ proc.start()
+ proc.join(3)
+ assert proc.exitcode is 0
+
+ # Check that connection is still alive after fork process has exited.
+ with pytest.raises(ConnectionError):
+ assert conn.send_command('ping') is None
+ assert conn.read_response() == b'PONG'
+
+ def test_close_connection_in_main(self):
+ conn = Connection()
+ assert conn.send_command('ping') is None
+ assert conn.read_response() == b'PONG'
+
+ def target(conn, ev):
+ ev.wait()
+ assert conn.send_command('ping') is None
+ assert conn.read_response() == b'PONG'
+
+ ev = multiprocessing.Event()
+ proc = multiprocessing.Process(target=target, args=(conn, ev))
+ proc.start()
+
+ conn.disconnect()
+ ev.set()
+
+ proc.join(3)
+ assert proc.exitcode is 1
+
+ @pytest.mark.parametrize('max_connections', [1, 2, None])
+ def test_pool(self, max_connections):
+ pool = ConnectionPool.from_url('redis://localhost',
+ max_connections=max_connections)
+
+ conn = pool.get_connection('ping')
+ with exit_callback(pool.release, conn):
+ assert conn.send_command('ping') is None
+ assert conn.read_response() == b'PONG'
+
+ def target(pool):
+ with exit_callback(pool.disconnect):
+ conn = pool.get_connection('ping')
+ with exit_callback(pool.release, conn):
+ assert conn.send_command('ping') is None
+ assert conn.read_response() == b'PONG'
+
+ proc = multiprocessing.Process(target=target, args=(pool,))
+ proc.start()
+ proc.join(3)
+ assert proc.exitcode is 0
+
+ # Check that connection is still alive after fork process has exited.
+ conn = pool.get_connection('ping')
+ with exit_callback(pool.release, conn):
+ with pytest.raises(ConnectionError):
+ assert conn.send_command('ping') is None
+ assert conn.read_response() == b'PONG'
+
+ @pytest.mark.parametrize('max_connections', [1, 2, None])
+ def test_close_pool_in_main(self, max_connections):
+ pool = ConnectionPool.from_url('redis://localhost',
+ max_connections=max_connections)
+
+ conn = pool.get_connection('ping')
+ assert conn.send_command('ping') is None
+ assert conn.read_response() == b'PONG'
+
+ def target(pool, disconnect_event):
+ conn = pool.get_connection('ping')
+ with exit_callback(pool.release, conn):
+ assert conn.send_command('ping') is None
+ assert conn.read_response() == b'PONG'
+ disconnect_event.wait()
+ assert conn.send_command('ping') is None
+ assert conn.read_response() == b'PONG'
+
+ ev = multiprocessing.Event()
+
+ proc = multiprocessing.Process(target=target, args=(pool, ev))
+ proc.start()
+
+ pool.disconnect()
+ ev.set()
+ proc.join(3)
+ assert proc.exitcode is 0
+
+ def test_redis(self, r):
+ assert r.ping() is True
+
+ def target(redis):
+ assert redis.ping() is True
+ del redis
+
+ proc = multiprocessing.Process(target=target, args=(r,))
+ proc.start()
+ proc.join(3)
+ assert proc.exitcode is 0
+
+ assert r.ping() is True