[Zope-Checkins] SVN: Zope/trunk/ - Collector #1939: When running as a service, Zope could

Sidnei da Silva sidnei at enfoldsystems.com
Wed Dec 21 07:15:37 EST 2005


Log message for revision 40950:
  
        - Collector #1939: When running as a service, Zope could
          potentially collect too much log output filling the NT Event
          Log. When that happened, a 'print' during exception handling
          would cause an IOError in the restart code causing the service
          not to restart automatically.
  
          Problem is that a service/pythonw.exe process *always* has an
          invalid sys.stdout.  But due to the magic of buffering, small
          print statements would not fail - but once the file actually
          got written to, the error happened.  Never a problem when
          debugging, as the process has a console, and hence a valid
          stdout.
  

Changed:
  U   Zope/trunk/doc/CHANGES.txt
  U   Zope/trunk/lib/python/nt_svcutils/service.py

-=-
Modified: Zope/trunk/doc/CHANGES.txt
===================================================================
--- Zope/trunk/doc/CHANGES.txt	2005-12-21 12:13:57 UTC (rev 40949)
+++ Zope/trunk/doc/CHANGES.txt	2005-12-21 12:15:36 UTC (rev 40950)
@@ -124,6 +124,19 @@
 
     Bugs Fixed
 
+      - Collector #1939: When running as a service, Zope could
+        potentially collect too much log output filling the NT Event
+        Log. When that happened, a 'print' during exception handling
+        would cause an IOError in the restart code causing the service
+        not to restart automatically.
+
+        Problem is that a service/pythonw.exe process *always* has an
+        invalid sys.stdout.  But due to the magic of buffering, small
+        "print" statements would not fail - but once the file actually
+        got written to, the error happened.  Never a problem when
+        debugging, as the process has a console, and hence a valid
+        stdout.
+
       - For content-type HTTP headers starting with 'text/' or 'application/'
         the 'charset' field is automatically if not specified by the
         application. The 'charset' is determined by the content-type header

Modified: Zope/trunk/lib/python/nt_svcutils/service.py
===================================================================
--- Zope/trunk/lib/python/nt_svcutils/service.py	2005-12-21 12:13:57 UTC (rev 40949)
+++ Zope/trunk/lib/python/nt_svcutils/service.py	2005-12-21 12:15:36 UTC (rev 40950)
@@ -36,8 +36,10 @@
 # (except obviously via the event log entry)
 # Size of the blocks we read from the child process's output.
 CHILDCAPTURE_BLOCK_SIZE = 80
-# The number of BLOCKSIZE blocks we keep as process output.
-CHILDCAPTURE_MAX_BLOCKS = 200
+# The number of BLOCKSIZE blocks we keep as process output.  This gives
+# is 4k, which should be enough to see any tracebacks etc, but not so
+# large as to prematurely fill the event log.
+CHILDCAPTURE_MAX_BLOCKS = 50
 
 class Service(win32serviceutil.ServiceFramework):
     """Base class for a Windows Server to manage an external process.
@@ -108,7 +110,10 @@
         except win32api.error, details:
             # Failed to write a log entry - most likely problem is
             # that the event log is full.  We don't want this to kill us
-            print "FAILED to write INFO event", event, ":", details
+            try:
+                print "FAILED to write INFO event", event, ":", details
+            except IOError:
+                pass
 
     def _dolog(self, func, msg):
         try:
@@ -118,8 +123,13 @@
         except win32api.error, details:
             # Failed to write a log entry - most likely problem is
             # that the event log is full.  We don't want this to kill us
-            print "FAILED to write event log entry:", details
-            print msg
+            try:
+                print "FAILED to write event log entry:", details
+                print msg
+            except IOError:
+                # And if running as a service, its likely our sys.stdout
+                # is invalid
+                pass
 
     def info(self, s):
         self._dolog(servicemanager.LogInfoMsg, s)



More information about the Zope-Checkins mailing list