[Mark Hammond]
> [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>.

[Tim Peters]
>> 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
>> exception.
>> 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
> diff -u -r1.1.2.3 service.py
> --- service.py  14 Apr 2005 01:47:48 -0000
> +++ service.py  19 Apr 2005 04:48:18 -0000
> @@ -234,7 +234,6 @@
>                                                win32event.INFINITE)
>         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).
Zope-Checkins maillist  -  Zope-Checkins@zope.org

Reply via email to