Skip to content

Commit

Permalink
Merge pull request #973 from billygout/master
Browse files Browse the repository at this point in the history
Cannot specify socket as blocking
  • Loading branch information
k4nar committed Apr 22, 2016
2 parents 5014c52 + e56bf94 commit bfb6204
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 4 deletions.
13 changes: 9 additions & 4 deletions circus/sockets.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class PapaSocketProxy(object):
def __init__(self, name='', host=None, port=None,
family=None, type=None,
proto=None, backlog=None, path=None, umask=None, replace=None,
interface=None, so_reuseport=False):
interface=None, so_reuseport=False, blocking=False):
if path is not None:
if not hasattr(socket, 'AF_UNIX'):
raise NotImplementedError("AF_UNIX not supported on this"
Expand Down Expand Up @@ -122,7 +122,7 @@ class CircusSocket(socket.socket):
def __init__(self, name='', host='localhost', port=8080,
family=socket.AF_INET, type=socket.SOCK_STREAM,
proto=0, backlog=2048, path=None, umask=None, replace=False,
interface=None, so_reuseport=False):
interface=None, so_reuseport=False, blocking=False):
if path is not None:
if not hasattr(socket, 'AF_UNIX'):
raise NotImplementedError("AF_UNIX not supported on this"
Expand All @@ -149,6 +149,7 @@ def __init__(self, name='', host='localhost', port=8080,
self.interface = interface
self.backlog = backlog
self.so_reuseport = so_reuseport
self.blocking = blocking

if self.so_reuseport and hasattr(socket, 'SO_REUSEPORT'):
try:
Expand Down Expand Up @@ -211,7 +212,10 @@ def bind_and_listen(self):
logger.error('Could not bind %s' % self.location)
raise

self.setblocking(0)
if self.blocking:
self.setblocking(1)
else:
self.setblocking(0)
if self.socktype in (socket.SOCK_STREAM, socket.SOCK_SEQPACKET):
self.listen(self.backlog)

Expand Down Expand Up @@ -241,7 +245,8 @@ def load_from_config(cls, config):
'backlog': int(config.get('backlog', 2048)),
'so_reuseport': to_bool(config.get('so_reuseport')),
'umask': int(config.get('umask', 8)),
'replace': config.get('replace')}
'replace': config.get('replace'),
'blocking': to_bool(config.get('blocking'))}
use_papa = to_bool(config.get('use_papa')) and papa is not None
proto_name = config.get('proto')
if proto_name is not None:
Expand Down
26 changes: 26 additions & 0 deletions circus/tests/test_sockets.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
except ImportError:
pass
import mock
import fcntl

from circus.tests.support import TestCase, skipIf, EasyTestSuite, IS_WINDOWS
from circus.sockets import CircusSocket, CircusSockets
Expand All @@ -19,6 +20,10 @@ def so_bindtodevice_supported():
pass
return False

def is_nonblock(fd):
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
nonblock = fl & os.O_NONBLOCK
return nonblock != 0

class TestSockets(TestCase):

Expand Down Expand Up @@ -108,6 +113,27 @@ def test_load_from_config_replace(self):
finally:
sock.close()

@skipIf(IS_WINDOWS, "Unix sockets not supported on this platform")
def test_load_from_config_blocking(self):
# test default to false
config = {'name': 'somename', 'host': 'localhost', 'port': 0}
sock = CircusSocket.load_from_config(config)
self.assertEqual(sock.blocking, False)
sock.bind_and_listen()
fl = fcntl.fcntl(sock.fileno(), fcntl.F_GETFL)
self.assertTrue(is_nonblock(sock.fileno()))
sock.close()

# test when true
config = {'name': 'somename', 'host': 'localhost', 'port': 0,
'blocking': True}
sock = CircusSocket.load_from_config(config)
self.assertEqual(sock.blocking, True)
sock.bind_and_listen()
fl2 = fcntl.fcntl(sock.fileno(), fcntl.F_GETFL)
self.assertFalse(is_nonblock(sock.fileno()))
sock.close()

@skipIf(IS_WINDOWS, "Unix sockets not supported on this platform")
def test_unix_socket(self):
sockfile = self._get_tmp_filename()
Expand Down
3 changes: 3 additions & 0 deletions docs/source/for-ops/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,9 @@ socket:NAME - as many sections as you want
If set to True and SO_REUSEPORT is available on target platform, circus
will create and bind new SO_REUSEPORT socket(s) for every worker it starts
which is a user of this socket(s).
**blocking**
If `True`, socket is set to blocking. If `False`, socket is set to non-blocking.
(default: False)

**use_papa**
Set to true to use the :ref:`papa`.
Expand Down

0 comments on commit bfb6204

Please sign in to comment.