Throttling connection limit of loop.create_server based servers

341 views
Skip to first unread message

Justin Mayfield

unread,
Oct 18, 2016, 2:39:07 PM10/18/16
to python-tulip
Is there a public interface for controlling the connection limit on servers created with `loop.create_server`?  Specifically a way to ~ `remove_reader(_accept_connection)` temporarily.

I've developed a statsd proxy for a client that needs to implement backpressure all the way to the listening socket but I don't see a good way to pause the _accept_connection handler that monitors the listening socket for read events.

I'd be happy to implement my own logic for the back pressure using a public `pause_serving()`/`resume_serving()` API but a simple `max_connections` param to the create_server would suffice too.

Cheers,
JM

Yury Selivanov

unread,
Oct 18, 2016, 2:43:02 PM10/18/16
to Justin Mayfield, python-tulip
Hi,

No, I don’t think we have an API for that. I suppose you can make a PR (or open an issue) at github.com/python/asyncio proposing to add `pause_serving()`/`resume_serving()`. I’m afraid we aren’t going to add them until 3.7, since Python 3.6 is in feature freeze mode now.

Yury

Guido van Rossum

unread,
Oct 18, 2016, 3:20:31 PM10/18/16
to Yury Selivanov, Justin Mayfield, python-tulip
Could you do this by changing listen()?
--
--Guido van Rossum (python.org/~guido)

Justin Mayfield

unread,
Oct 18, 2016, 3:59:48 PM10/18/16
to python-tulip, yseli...@gmail.com, too...@gmail.com, gu...@python.org
HI Guido,

If you're refering the the backlog param of listen(), this controls how many sockets the kernel will establish on your behalf when your accept() calls fall behind the incoming connection rate.   E.g. an accept queue.  There is a good write up here http://veithen.github.io/2014/01/01/how-tcp-backlog-works-in-linux.html.

I need a way to prevent accept() from running so I can actually bump up against the listen() backlog and not run out of memory when I get flooded with connections.

JM

Justin Mayfield

unread,
Oct 18, 2016, 4:10:42 PM10/18/16
to python-tulip, too...@gmail.com
Re 3.6 freeze, This is understandable.

I just wanted to make sure I wasn't missing something in the first place.  I can submit a PR/Issue that focuses on Server.pause_serving and resume_serving if that's the most sensible place for this.  A param to start_server such as `connection_limit` could be added later using those interfaces or I could add that in the same PR.


Mild tangent, while I was looking at the code I was wondering if it made sense to allow users to bring their own Server subclasses via an optional kwarg to create_server, along the lines of 

```
class MySuperServer(asyncio.Server):
     pass

my_super_server = await asyncio.start_server(..., server_class=MySuperServer)
```

Custom backpressure implementations could be made in Server subclasses this way.

JM

Yury Selivanov

unread,
Oct 18, 2016, 4:19:03 PM10/18/16
to Justin Mayfield, python-tulip

> On Oct 18, 2016, at 4:10 PM, Justin Mayfield <too...@gmail.com> wrote:
>
> Re 3.6 freeze, This is understandable.
>
> I just wanted to make sure I wasn't missing something in the first place. I can submit a PR/Issue that focuses on Server.pause_serving and resume_serving if that's the most sensible place for this. A param to start_server such as `connection_limit` could be added later using those interfaces or I could add that in the same PR.
>
>
> Mild tangent, while I was looking at the code I was wondering if it made sense to allow users to bring their own Server subclasses via an optional kwarg to create_server, along the lines of
>
> ```
> class MySuperServer(asyncio.Server):
> pass
>
> my_super_server = await asyncio.start_server(..., server_class=MySuperServer)
> ```

We try to avoid promoting use of inheritance in asyncio APIs, so my first reaction to this would be “no”. IMO pause_serving / resume_serving methods are easy to understand and use.

BTW, another way to solve your problem in asyncio in 3.6 is to create your own accept loop implementation and use the new 'loop. connect_accepted_socket' API.

Yury

Justin Mayfield

unread,
Oct 18, 2016, 4:30:42 PM10/18/16
to Yury Selivanov, python-tulip
That's interesting, I hadn't seen that method yet.  I'd still like to pursue pause/resume on Server for this use-case, but I might make use of that in the future for more complex servers.

JM

Justin Mayfield

unread,
Oct 19, 2016, 4:59:02 AM10/19/16
to Yury Selivanov, python-tulip
Reply all
Reply to author
Forward
0 new messages