[email@example.com: Re: [Zope-Checkins] CVS:
Zope/lib/python/nt_svcutils - service.py:220.127.116.11]
tim.peters at gmail.com
Tue Apr 19 11:23:59 EDT 2005
> [For some reason Tim's original still hasn't arrived!]
You know, from my POV that statement is pretty mysterious, since you
seem to be replying to my email here <wink>.
>> I'm trying to build a new ZRS release. Trying to stop the ZRS service
>> now "suddenly and for no reason at all" <wink> logs an error, because
>> I believe its onStop() method is getting called twice now, but used to
>> be called only once. That's no good for ZRS, because its onStop
>> method makes a connection to a special "shutdown port", and ZRS proper
>> responds by shutting ZRS down. The socket goes away along with it, so
>> trying to connect to the shutdown port a second time raises an
>> I'm not entirely sure why this didn't used to happen. I'm guessing
>> that a stop request with the current code:
>> 1. Triggers SvcStop, which calls onStop() and sets hWaitStop.
>> 2. Setting hWaitStop in turn triggers the WaitForMultipleObjects in run(),
>> and then that calls SvcStop again (which calls onStop() again).
>> Anyway, is this bug or feature? If it's a feature, I can make the ZRS
>> subclass onStop() methods safe to call multiple times. It doesn't
>> _feel_ like a feature, though <wink>.
> From the sounds of things it is a bug <wink>.
> FYI, SvcStop is called by the (Python win32serviceutil) framework when an
> external request comes in to stop the service.
I think that's my #1 above, and I think that part works fine here.
The tracebacks I see have run() in the call stack, which is why I
guess #2 is doing SvcStop it a second time.
> However, a service can stop also stop by its own accord.
I don't think ZRS ever does that, and am not sure how I could write
code to do it. Does a Zope service ever decide to "stop by its own
> The question, then, is under what cases should the onStop() calls be made? It
> sounds to me like you want it called only when that external request comes in.
Maybe. In the end, by whatever means a service gets shut down
(external, internal, whatever), I want to see the subclass onStop()
method called exactly once.
But that's mostly because that's what "used to happen" for the two
ZRS-related services, not because it's a Holy Principle I'd fight to
death to defend <wink>.
> Assuming that is the case, I believe both explicit calls to SvcStop() are
> bogus and can be removed completely. The report of
> SERVICE_STOP_PENDING will happen as soon as these functions return
> False. In both cases, it is not necessary to set hWaitStop as nothing is going
> to wait on it once these lines get hit. It seems we also don't want onStop()
> called at these times, so nothing the function does is necessary at those points.
> Also FYI, service.py is identical in both 2.7 and 2.8, so can be copied
> between them. I believe the diff you want is simply:
> RCS file: /cvs-repository/Zope/lib/python/nt_svcutils/Attic/service.py,v
> retrieving revision 18.104.22.168
> diff -u -r22.214.171.124 service.py
> --- service.py 14 Apr 2005 01:47:48 -0000 126.96.36.199
> +++ service.py 19 Apr 2005 04:48:18 -0000
> @@ -234,7 +234,6 @@
> if rc == win32event.WAIT_OBJECT_0:
> # user sent a stop service request
> - self.SvcStop()
> keep_running = False
> elif rc == win32event.WAIT_OBJECT_0 + 1:
> # user did not send a service stop request, but
> @@ -261,7 +260,6 @@
> # this was an abormal shutdown.
> if self.backoff_cumulative > BACKOFF_MAX:
> self.error("restarting too frequently; quit")
> - self.SvcStop()
> return False
> self.warning("sleep %s to avoid rapid restarts"
> % self.backoff_interval)
> That seems to work fine here.
Seems to work fine for the ZRS-related services too, although I didn't
get into the "restarting too frequently" branch. Thank you. If
nobody objects in the next 10 minutes, then, I'll check this in (and
port to Zope trunk (2.8) too).
More information about the Zope-Checkins