[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 accord"? > 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 1.1.2.3 > diff -u -r1.1.2.3 service.py > --- service.py 14 Apr 2005 01:47:48 -0000 1.1.2.3 > +++ 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 http://mail.zope.org/mailman/listinfo/zope-checkins