Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Python: Dev

SocketServer issues

 

 

Python dev RSS feed   Index | Next | Previous | View Threaded


kristjan at ccpgames

Mar 13, 2012, 9:26 PM

Post #1 of 14 (243 views)
Permalink
SocketServer issues

Hi there.
I want to mention some issues I've had with the socketserver module, and discuss if there's a way to make it nicer.
So, for a long time we were able to create magic stackless mixin classes for it, like ThreadingMixIn, and assuming we had the appropriate socket replacement library, be able to use it nicely using tasklets.
Then, at some point, the run_forever loop was changed to support timeout through the use of select.select() before every socket.accept() call. This was very awkward because the whole concept of select() really goes contrary to the approach of using microthreads, non-blocking IO and all that.
The only reason for this select call, was to support timeout for the accept. And even for vanilla applications, it necessiates an extra kernel call for every accept, just for the timeout.

The way around this for me has to do local modifications to the SocketServer and just get rid of the select.

So, my first question is: Why not simply rely on the already built-in timeout support in the socket module? Setting the correct timeout value on the accepting socket, will achieve the same thing. Of course, one then has to reset the timeout value on the accepted socket, but this is minor.

Second: Of late the SocketServer has grown additional features and attributes. In particular, it now has two event objects, __shutdown_request and __is_shut_down.
Notice the double underscores.
They make it impossible to subclass the SocketServer class to provide a different implementation of run_forever(). Is there any good reason why these attributes have been made "private" like this? Having just seen Raymond's talk on how to subclass right, this looks like the wrong way to use the double leading underscores.

So, two things really:
The use of select.select in SocketServer makes it necessary to subclass it to write a new version of run_forever() for those that wish to use a non-blocking IO library instead of socket. And the presence of these private attributes make it (theoretically) impossible to specialize run_forever in a mix-in class.

Any thoughs? Is anyone interested in seeing how the timeouts can be done without using select.select()? And what do you think about removing the double underscores from there and thus making serve_forever owerrideable?

Kristján


solipsis at pitrou

Mar 14, 2012, 2:02 AM

Post #2 of 14 (231 views)
Permalink
Re: SocketServer issues [In reply to]

On Wed, 14 Mar 2012 04:26:16 +0000
Kristján Valur Jónsson <kristjan [at] ccpgames> wrote:
> Hi there.
> I want to mention some issues I've had with the socketserver module, and discuss if there's a way to make it nicer.
> So, for a long time we were able to create magic stackless mixin classes for
> it, like ThreadingMixIn, and assuming we had the appropriate socket
> replacement library, be able to use it nicely using tasklets.

I don't really think the ability to "create magic stackless mixin
classes" should be a driving principle for the stdlib.
I would suggest using a proper non-blocking framework such as Twisted.

> So, my first question is: Why not simply rely on the already built-in timeout
> support in the socket module?

In case you didn't notice, the built-in timeout support *also* uses
select().

Regards

Antoine.


_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


guido at python

Mar 14, 2012, 8:27 AM

Post #3 of 14 (232 views)
Permalink
Re: SocketServer issues [In reply to]

Hopefully it doesn't use select if no timeout is set...

--Guido van Rossum (sent from Android phone)
On Mar 14, 2012 2:08 AM, "Antoine Pitrou" <solipsis [at] pitrou> wrote:

> On Wed, 14 Mar 2012 04:26:16 +0000
> Kristján Valur Jónsson <kristjan [at] ccpgames> wrote:
> > Hi there.
> > I want to mention some issues I've had with the socketserver module, and
> discuss if there's a way to make it nicer.
> > So, for a long time we were able to create magic stackless mixin classes
> for
> > it, like ThreadingMixIn, and assuming we had the appropriate socket
> > replacement library, be able to use it nicely using tasklets.
>
> I don't really think the ability to "create magic stackless mixin
> classes" should be a driving principle for the stdlib.
> I would suggest using a proper non-blocking framework such as Twisted.
>
> > So, my first question is: Why not simply rely on the already built-in
> timeout
> > support in the socket module?
>
> In case you didn't notice, the built-in timeout support *also* uses
> select().
>
> Regards
>
> Antoine.
>
>
> _______________________________________________
> Python-Dev mailing list
> Python-Dev [at] python
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> http://mail.python.org/mailman/options/python-dev/guido%40python.org
>


pje at telecommunity

Mar 14, 2012, 9:17 AM

Post #4 of 14 (231 views)
Permalink
Re: SocketServer issues [In reply to]

On Wed, Mar 14, 2012 at 5:02 AM, Antoine Pitrou <solipsis [at] pitrou> wrote:

> On Wed, 14 Mar 2012 04:26:16 +0000
> Kristján Valur Jónsson <kristjan [at] ccpgames> wrote:
> > Hi there.
> > I want to mention some issues I've had with the socketserver module, and
> discuss if there's a way to make it nicer.
> > So, for a long time we were able to create magic stackless mixin classes
> for
> > it, like ThreadingMixIn, and assuming we had the appropriate socket
> > replacement library, be able to use it nicely using tasklets.
>
> I don't really think the ability to "create magic stackless mixin
> classes" should be a driving principle for the stdlib.
>

But not needlessly duplicating functionality already elsewhere in the
stdlib probably ought to be. ;-)


> So, my first question is: Why not simply rely on the already built-in
> timeout
> > support in the socket module?
>
> In case you didn't notice, the built-in timeout support *also* uses
> select().
>

That's not really the point; the frameworks that implement nonblocking I/O
by replacing the socket module (and Stackless is only one of many) won't be
using that code. If SocketServer uses only the socket module's API, then
those frameworks will be told about the timeout via the socket API, and can
then implement it their own way.


solipsis at pitrou

Mar 14, 2012, 9:28 AM

Post #5 of 14 (232 views)
Permalink
Re: SocketServer issues [In reply to]

On Wed, 14 Mar 2012 08:27:08 -0700
Guido van Rossum <guido [at] python> wrote:
> Hopefully it doesn't use select if no timeout is set...

No, it doesn't :-)

Regards

Antoine.
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


solipsis at pitrou

Mar 14, 2012, 9:29 AM

Post #6 of 14 (231 views)
Permalink
Re: SocketServer issues [In reply to]

On Wed, 14 Mar 2012 12:17:06 -0400
PJ Eby <pje [at] telecommunity> wrote:
>
> > So, my first question is: Why not simply rely on the already built-in
> > timeout
> > > support in the socket module?
> >
> > In case you didn't notice, the built-in timeout support *also* uses
> > select().
> >
>
> That's not really the point; the frameworks that implement nonblocking I/O
> by replacing the socket module (and Stackless is only one of many) won't be
> using that code.

Then they should also replace the select module.
Again, I don't think SocketServer (or any other stdlib module) should
be designed in this regard.

Regards

Antoine.
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


guido at python

Mar 14, 2012, 9:44 AM

Post #7 of 14 (228 views)
Permalink
Re: SocketServer issues [In reply to]

2012/3/13 Kristján Valur Jónsson <kristjan [at] ccpgames>:
> I want to mention some issues I‘ve had with the socketserver module, and
> discuss if there‘s a way to make it nicer.
>
> So, for a long time we were able to create magic stackless mixin classes for
> it, like ThreadingMixIn, and assuming we had the appropriate socket
> replacement library, be able to use it nicely using tasklets.
>
> Then, at some point, the run_forever loop was changed to support timeout
> through the use of select.select() before every socket.accept() call.  This
> was very awkward because the whole concept of select() really goes contrary
> to the approach of using microthreads, non-blocking IO and all that.

I'm surprised -- surely a non-blocking framework should have no
problem implementing select(), especially if it's for one file
descriptor?

> The only reason for this select call, was to support timeout for the
> accept.  And even for vanilla applications, it necessiates an extra kernel
> call for every accept, just for the timeout.

I think it's fine to change the code so that if poll_interval is
explicitly set to None, the select() call is skipped. I don't think
the default should change though. The select() call is normally needed
to support the shutdown() feature, which is very useful. And also the
overridable service_actions() method.

Oh, there's another select() call, in handle_request(), that should
also be skipped if timeout is None.

At least, I *think* a select() with a timeout of None blocks forever
or until the socket is ready or until it is interrupted; I think this
can always be skipped, since the immediately following I/O call will
block in exactly the same way. Unless the socket is set in
non-blocking mode; we may have to have provisions to avoid breaking
that situation too.

> The way around this for me has to do local modifications to the SocketServer
> and just get rid of the select.

I hope the above suggestion is sufficient? It's the best we can do
while maintaining backward compatibility. This class has a lot of
different features, and is designed to be subclassed, so it's hard to
make changes that don't break anything.

> So, my first question is:  Why not simply rely on the already built-in
> timeout support in the socket module?  Setting the correct timeout value on
> the accepting socket, will achieve the same thing.  Of course, one then has
> to reset the timeout value on the accepted socket, but this is minor.

I don't think it's the same thing at all. If you set a timeout on the
socket, the accept() or recvfrom() call in get_request() will raise an
exception if no request comes in within the timeout (default 0.5 sec);
with the timeout implemented in serve_forever(), get_request() and its
callers won't have to worry about the timeout exception.

> Second: Of late the SocketServer has grown additional features and
> attributes.  In particular, it now has two event objects, __shutdown_request
> and __is_shut_down.
>
> Notice the double underscores.
>
> They make it impossible to subclass the SocketServer class to provide a
> different implementation of run_forever().  Is there any good reason why
> these attributes have been made „private“ like this?  Having just seen
> Raymond‘s talk on how to subclass right, this looks like the wrong way to
> use the double leading underscores.

Assuming you meant serve_forever(), I see no problem at all. If you
override serve_forever() you also have to override shutdown(). That's
all. They are marked private because they are involved in subtle
invariants that are easily disturbed if users touch them.

I could live with making them single-underscore protected, only to be
used by knowledgeable subclasses. But not with making then public
attributes.

> So, two things really:
>
> The use of select.select in SocketServer makes it necessary to subclass it
> to write a new version of run_forever() for those that wish to use a
> non-blocking IO library instead of socket. And the presence of these private
> attributes make it (theoretically) impossible to specialize run_forever in a
> mix-in class.
>
>
>
> Any thoughs?  Is anyone interested in seeing how the timeouts can be done
> without using select.select()?  And what do you think about removing the
> double underscores from there and thus making serve_forever owerrideable?

Let's see a patch (based on my concerns above) and then we can talk again.

--
--Guido van Rossum (python.org/~guido)
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


kristjan at ccpgames

Mar 14, 2012, 9:59 AM

Post #8 of 14 (233 views)
Permalink
Re: SocketServer issues [In reply to]

>I don't really think the ability to "create magic stackless mixin classes" should be a driving principle for the stdlib.
> I would suggest using a proper non-blocking framework such as Twisted.

There is a lot of code out there that uses SocketServer. It was originally designed to be easily extensable, with various mixins to control ultimate
Behavior. It just seems that there have been some design decisions made recently that make this subclassability / extensibility more difficult, and those
Are the two changes I pointed out. The thing with the select.select wouldn't be so bad if I could simply override serve_forever but that function
Can't be overridden because of the poor choice of adding __attributes to the class.

And, you would run into the same kind of trouble if you wanted to create a TwistedMixIn, a geventMixIn, or what not.

> In case you didn't notice, the built-in timeout support *also* uses select().
Yes, that's how the normal blocking framework supports timeout. Asynchronous frameworks do it differently, though.

> Then they should also replace the select module.
> Again, I don't think SocketServer (or any other stdlib module) should be designed in this regard.

And so we do too, but now every socket accept requires two rounds round the event loop. Also, emulating select() is not a critical part of frameworks designed to help you avoid to use it in the first place. The point of frameworks such as gevent, stackless, etc, is to let you write code with zillions of sockets without ever touching select. The quick and dirty emulated version I use, uses a thread to make it non-blocking!

It just seems odd to me that it was designed to use the "select" api to do timeouts, where timeouts are already part of the socket protocol and can be implemented more efficiently there.

Anyway, I'm not talking about rewriting anything, I merely want to fix some small design problems that prevent SocketServer to be specialized. I'll submit a simple patch for review.

K
-----Original Message-----
From: python-dev-bounces+kristjan=ccpgames.com [at] python [mailto:python-dev-bounces+kristjan=ccpgames.com [at] python] On Behalf Of Antoine Pitrou
Sent: 14. mars 2012 02:02
To: python-dev [at] python
Subject: Re: [Python-Dev] SocketServer issues

On Wed, 14 Mar 2012 04:26:16 +0000
Kristján Valur Jónsson <kristjan [at] ccpgames> wrote:
> Hi there.
> I want to mention some issues I've had with the socketserver module, and discuss if there's a way to make it nicer.
> So, for a long time we were able to create magic stackless mixin
> classes for it, like ThreadingMixIn, and assuming we had the
> appropriate socket replacement library, be able to use it nicely using tasklets.

I don't really think the ability to "create magic stackless mixin classes" should be a driving principle for the stdlib.
I would suggest using a proper non-blocking framework such as Twisted.

> So, my first question is: Why not simply rely on the already built-in
> timeout support in the socket module?

In case you didn't notice, the built-in timeout support *also* uses select().

Regards

Antoine.


_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/kristjan%40ccpgames.com


_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


pje at telecommunity

Mar 14, 2012, 10:03 AM

Post #9 of 14 (230 views)
Permalink
Re: SocketServer issues [In reply to]

On Wed, Mar 14, 2012 at 12:29 PM, Antoine Pitrou <solipsis [at] pitrou>wrote:

> On Wed, 14 Mar 2012 12:17:06 -0400
> PJ Eby <pje [at] telecommunity> wrote:
> > That's not really the point; the frameworks that implement nonblocking
> I/O
> > by replacing the socket module (and Stackless is only one of many) won't
> be
> > using that code.
>
> Then they should also replace the select module.
>

That actually sounds like a good point. ;-)

I'm not the maintainer of any of those frameworks, but IIRC some of them
*do* replace it. Perhaps this would solve Stackless's problem here too?


solipsis at pitrou

Mar 14, 2012, 10:23 AM

Post #10 of 14 (231 views)
Permalink
Re: SocketServer issues [In reply to]

On Wed, 14 Mar 2012 16:59:47 +0000
Kristján Valur Jónsson <kristjan [at] ccpgames> wrote:
>
> It just seems odd to me that it was designed to use the "select" api to do timeouts, > where timeouts are already part of the socket protocol and can be implemented more
> efficiently there.

How is it more efficient if it uses the exact same system calls?
And why are you worrying exactly? I don't understand why accept() would
be critical for performance.

Thanks

Antoine.


_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


kristjan at ccpgames

Mar 14, 2012, 11:37 AM

Post #11 of 14 (231 views)
Permalink
Re: SocketServer issues [In reply to]

A different implementation, (e.g. one using windows IOCP), can do timeouts without using select (and must, select does not work with IOCP). So will a gevent based implementation, it will timeout the accept on each socket individually, not by calling select on each of them.

The reason I'm fretting is latency. There is only one thread accepting connections. If it has to do an extra event loop dance for every socket that it accepts that adds to the delay in getting a response from the server. Accept() is indeed critical for socket server performance.

Maybe this is all just nonsense, still it seems odd to jump through extra hoops to emulate a functionality that is already supported by the socket spec, and can be done in the most appropriate way for each implementation.

K

-----Original Message-----
From: python-dev-bounces+kristjan=ccpgames.com [at] python [mailto:python-dev-bounces+kristjan=ccpgames.com [at] python] On Behalf Of Antoine Pitrou
Sent: 14. mars 2012 10:23
To: python-dev [at] python
Subject: Re: [Python-Dev] SocketServer issues

On Wed, 14 Mar 2012 16:59:47 +0000
Kristján Valur Jónsson <kristjan [at] ccpgames> wrote:
>
> It just seems odd to me that it was designed to use the "select" api
> to do timeouts, > where timeouts are already part of the socket protocol and can be implemented more efficiently there.

How is it more efficient if it uses the exact same system calls?
And why are you worrying exactly? I don't understand why accept() would be critical for performance.

Thanks

Antoine.



_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


guido at python

Mar 14, 2012, 11:43 AM

Post #12 of 14 (230 views)
Permalink
Re: SocketServer issues [In reply to]

2012/3/14 Kristján Valur Jónsson <kristjan [at] ccpgames>:
> Maybe this is all just nonsense, still it seems odd to jump through extra hoops to emulate a functionality that is already supported by the socket spec, and can be done in the most appropriate way for each implementation.

I thought I had already explained why setting the timeout on the
socket is not the same.

--
--Guido van Rossum (python.org/~guido)
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


kristjan at ccpgames

Mar 14, 2012, 12:35 PM

Post #13 of 14 (226 views)
Permalink
Re: SocketServer issues [In reply to]

Yes, setting a timeout and leaving it that way is not the same. But setting the timeout for _accept only_ is the "same" except one approach requires the check of a bool return, the other the handling of a socket.timeout exeption.
My point is, if sockets already have nice and well defined timeout semantics, why not use them, or even improve them (perhaps with an optional timeout parameter to the accept call) rather than reimplement them with an explicit select.select() call?

Anyway, I'll take another look at the problem and possibly submit a patch suggestion. Thanks.

K

-----Original Message-----
From: gvanrossum [at] gmail [mailto:gvanrossum [at] gmail] On Behalf Of Guido van Rossum
Sent: 14. mars 2012 11:44
To: Kristján Valur Jónsson
Cc: Antoine Pitrou; python-dev [at] python
Subject: Re: [Python-Dev] SocketServer issues

2012/3/14 Kristján Valur Jónsson <kristjan [at] ccpgames>:
> Maybe this is all just nonsense, still it seems odd to jump through extra hoops to emulate a functionality that is already supported by the socket spec, and can be done in the most appropriate way for each implementation.

I thought I had already explained why setting the timeout on the socket is not the same.

--
--Guido van Rossum (python.org/~guido)


_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


kristjan at ccpgames

Mar 14, 2012, 5:40 PM

Post #14 of 14 (215 views)
Permalink
Re: SocketServer issues [In reply to]

Fyi:
http://bugs.python.org/issue14307


-----Original Message-----
From: python-dev-bounces+kristjan=ccpgames.com [at] python [mailto:python-dev-bounces+kristjan=ccpgames.com [at] python] On Behalf Of Kristján Valur Jónsson
Sent: 14. mars 2012 12:36
To: Guido van Rossum
Cc: Antoine Pitrou; python-dev [at] python
Subject: Re: [Python-Dev] SocketServer issues

Yes, setting a timeout and leaving it that way is not the same. But setting the timeout for _accept only_ is the "same" except one approach requires the check of a bool return, the other the handling of a socket.timeout exeption.
My point is, if sockets already have nice and well defined timeout semantics, why not use them, or even improve them (perhaps with an optional timeout parameter to the accept call) rather than reimplement them with an explicit select.select() call?

Anyway, I'll take another look at the problem and possibly submit a patch suggestion. Thanks.

K

-----Original Message-----
From: gvanrossum [at] gmail [mailto:gvanrossum [at] gmail] On Behalf Of Guido van Rossum
Sent: 14. mars 2012 11:44
To: Kristján Valur Jónsson
Cc: Antoine Pitrou; python-dev [at] python
Subject: Re: [Python-Dev] SocketServer issues

2012/3/14 Kristján Valur Jónsson <kristjan [at] ccpgames>:
> Maybe this is all just nonsense, still it seems odd to jump through extra hoops to emulate a functionality that is already supported by the socket spec, and can be done in the most appropriate way for each implementation.

I thought I had already explained why setting the timeout on the socket is not the same.

--
--Guido van Rossum (python.org/~guido)


_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/kristjan%40ccpgames.com


_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com

Python dev RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.