classification
Title: socketserver can't stop
Type: behavior Stage: test needed
Components: Library (Lib) Versions: Python 3.2, Python 3.3, Python 2.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: giampaolo.rodola, martin.panter, r.david.murray, teamnoir, weirdink13
Priority: normal Keywords:

Created on 2012-01-09 19:19 by teamnoir, last changed 2016-02-11 03:32 by martin.panter.

Files
File name Uploaded Description Edit
tryfixsocketserver.py weirdink13, 2012-04-07 01:12
Messages (9)
msg150965 - (view) Author: K Richard Pixley (teamnoir) Date: 2012-01-09 19:19
Once I've instantiated my server class, along with a handler class, called server.serve_forever(), handler.handle() has been called, I've done my work, and I'm ready to shut the whole thing down...

How do I do that?

The doc says server.shutdown(), but if I call self.server.shutdown() from within handler.handle(), I seem to get a deadlock, which is exactly what I'd expect in a single threaded system with no way to "signal" the server.server_forever() loop which is several frames up the stack.

I've also tried sys.exit() but it seems that the server object is catching that as an exception.

How is this expected to work?  How do I terminate the server.serve_forever() loop?

Both 3.2 and 2.7 appear to behave the same way.  The documentation is confusing here as it doesn't explain what is expected to happen in this case.
msg150966 - (view) Author: K Richard Pixley (teamnoir) Date: 2012-01-09 19:21
It appears as though the problem is that shutdown() blocks waiting for the serve_forever loop to terminate, which won't happen as long as the process is blocked on shutdown.

I'd like to propose that the library be changed to eliminate the block.  Shutdown() can set the flag and then return.  This should allow the handler to return and the serve_forever loop to notice that it has been asked to cease operations.

Failing that, I think the library needs some other way to exit a socketserver.
msg150968 - (view) Author: K Richard Pixley (teamnoir) Date: 2012-01-09 19:28
On second thought, my proposal is likely to break existing code, so I withdraw it.

I don't know how to exit the server in a way that both works in all conditions and also continues to support existing semantics.

I expect we'll need to create a new call.  Perhaps "request_shutdown" which simply sets the flag without waiting?
msg157103 - (view) Author: Daniel Swanson (weirdink13) Date: 2012-03-29 21:15
What about os._exit?
or CTR-ALT-DEL (windows only)
I'd say that socketserver.serveforever is very well named (Hey, if you can't turn it off then it's serving forever)
msg157109 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2012-03-29 22:35
At the very least the docs should be clarified to say that you have to call shutdown from a separate thread.  (The one example of using it does do that.)

I don't have a strong opinion about the proposed new method, not having used socketserver except for running in to it in stdlib test files.  It sounds reasonable enough.
msg157674 - (view) Author: Daniel Swanson (weirdink13) Date: 2012-04-06 18:37
what about this?
def __init__(...):
    ...
    self.stop = False
    while True:
        (do stuff)
        if self.stop: break
def quit(or whatever it's called): self.stop = True
That would work without the backwards copatability issue right?
msg157677 - (view) Author: Daniel Swanson (weirdink13) Date: 2012-04-06 19:01
Or even better:
def __init__(...):
    ...
    self.stop = False
    while not self.stop:
        (do stuff)
def quit(or whatever it's called): self.stop = True
msg157712 - (view) Author: Daniel Swanson (weirdink13) Date: 2012-04-07 01:12
I tryed to fix the problem, here is my attemt.
msg260071 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2016-02-11 03:32
For stopping a single-threaded server from a request handler, perhaps see my patch for Issue 23430, which should allow calling sys.exit() or raising exceptions like SystemExit that do not inherit Exception.

It seems to me that shutdown() can only sensibly be used from a separate thread. If a forking server is used, that thread would have to be in the initial server listening process. See also Issue 12463 for some proposals for changing shutdown().
History
Date User Action Args
2016-02-11 03:32:20martin.pantersetnosy: + martin.panter
messages: + msg260071
2012-04-07 01:12:19weirdink13setfiles: + tryfixsocketserver.py

messages: + msg157712
2012-04-06 19:01:56weirdink13setmessages: + msg157677
2012-04-06 18:37:25weirdink13setmessages: + msg157674
2012-03-29 22:35:10r.david.murraysetnosy: + r.david.murray
messages: + msg157109
2012-03-29 21:15:58weirdink13setnosy: + weirdink13
messages: + msg157103
2012-03-27 14:23:25giampaolo.rodolasetnosy: + giampaolo.rodola
2012-01-14 05:17:43terry.reedysetstage: test needed
versions: + Python 3.3
2012-01-09 19:28:07teamnoirsetmessages: + msg150968
2012-01-09 19:21:37teamnoirsetmessages: + msg150966
2012-01-09 19:19:28teamnoircreate