Author: chrisz
Date: Sat Apr 8 13:47:43 2006
New Revision: 5012
Modified:
Webware/trunk/WebKit/Docs/AppServer.configlist
Webware/trunk/WebKit/Docs/Configuration.txt
Webware/trunk/WebKit/Docs/RelNotes-X.Y.phtml
Webware/trunk/WebKit/Monitor.py
Webware/trunk/WebKit/ThreadedAppServer.py
Log:
The Monitor.py program and the monitor service were both broken and should now be working again.
Modified: Webware/trunk/WebKit/Docs/AppServer.configlist
==============================================================================
--- Webware/trunk/WebKit/Docs/AppServer.configlist (original)
+++ Webware/trunk/WebKit/Docs/AppServer.configlist Sat Apr 8 13:47:43 2006
@@ -1,17 +1,30 @@
[
+
('PrintConfigAtStartUp', '1', "Does what it says. It's generally a good idea to leave this on."),
('Verbose', '1', "If true, then additional messages are printed while the AppServer runs, most notably information about each request such as size and response time."),
('Host', '127.0.0.1', "The host that the application server runs on. There is little reason to ever change this."),
-('Port', '8086', "The port that the application server runs on. Change this if there is a conflict with another application on your server."),
+('EnableAdapter', '1', "Whether the application server should listen for requests from the adapter. You'll want this on unless you decide to use the built-in HTTP server."),
+
+('AdapterPort', '8086', "The port that the application server runs on. Change this if there is a conflict with another application on your server."),
+
+('EnableHTTP', '1', "Activate the built-in HTTP server. The HTTP server will listen on the port specified by the <span class="name">HTTPPort</span> setting."),
+
+('HTTPPort', '8080', "The port the built-in HTTP server listens on. You can point a browser to this port."),
+
+('EnableMonitor', '0', "Whether the application server should listen for requests on the monitor port. Monitor is a minimal service that accepts a simple protocol and returns a value indicating the status of the server. If you enable this, a separate monitoring process can provide additional assurance that the application server continues running at all times."),
+
+('MonitorPort', '8085', "The port that the monitor service runs on. Change this if there is a conflict with another application on your server."),
+
+('PidFile', 'appserverpid.txt', "When the AppServer starts up, the process id will be written into this file. The path will be relative to the working directory (or WebKit path, if you're not using a working directory), or you can specify an absolute path."),
-('PlugIns', "[]", "Loads the plug-ins from the given locations when the application server starts up. This setting isn't as popular as <span class=name>PlugInDirs</span> below since it requires an update for every new plug-in created."),
+('PlugIns', "[]", "Loads the plug-ins from the given locations when the application server starts up. This setting isn't as popular as <span class="name">PlugInDirs</span> below since it requires an update for every new plug-in created."),
('PlugInDirs', "['..']", '''A list of directories where WebKit plug-ins can be detected and loaded when the application server starts up. Relative paths are relative to the WebKit directory. Webware already ships with several plug-ins (hence the '..'). You can also create your own plug-ins.
- <br><br> A plug-in must have <span class=filename>__init__.py</span> and <span class=filename>Properties.py</span> files. You can disable a specific plug-in by placing a <span class=filename>dontload</span> file in it.
+ <br><br> A plug-in must have <span class="filename">__init__.py</span> and <span class="filename">Properties.py</span> files. You can disable a specific plug-in by placing a <span class="filename">dontload</span> file in it.
<br><br> The advantage of a plug-in directory is that you can add new plug-ins to the app server simply by dropping them into the directory; no additional configuration is necessary.'''),
@@ -19,9 +32,9 @@
('CheckInterval', '100', 'The number of virtual instructions after which Python will check for thread switches, signal handlers, etc. This is passed directly to sys.setcheckinterval(). Benchmarks have shown 100 to give a worthwhile performance boost with higher values resulting in little gain.'),
-('AutoReload', '0', 'If true, the application server will monitor all source files for modifications, and will restart itself as necessary to pick up changes. This feature only works on posix systems.'),
+('AutoReload', '0', 'If true, the application server will monitor all source files for modifications, and will restart itself as necessary to pick up changes. This feature only works on posix systems.'),
-('AutoReloadPollInterval', '1', 'If AutoReload is activated and FAM (File Alternation Monitor) is not installed or ImportSpy is deactivated, the application server will periodically check for source files for changes. This setting specifies the number of seconds to wait between checking the source files.'),
+('AutoReloadPollInterval', '1', 'If AutoReload is activated and FAM (File Alteration Monitor) is not installed or ImportSpy is deactivated, the application server will periodically check for source files for changes. This setting specifies the number of seconds to wait between checking the source files.'),
('UseImportSpy', '1', "If this is set to true, ImportSpy will be used for keeping track of imported modules. Since this can lead to problems with incompatible importing mechanisms, the use of ImportSpy can be completely disabled by setting UseImportSpy to false. In this case, the AutoReload feature falls back to periodically checking sys.modules."),
Modified: Webware/trunk/WebKit/Docs/Configuration.txt
==============================================================================
--- Webware/trunk/WebKit/Docs/Configuration.txt (original)
+++ Webware/trunk/WebKit/Docs/Configuration.txt Sat Apr 8 13:47:43 2006
@@ -345,11 +345,24 @@
be listening at a different port. Default: ``8086``.
``EnableHTTP``:
Activate the built-in HTTP server. The HTTP server will listen
- on the port specified by the ``HTTPPort`` setting.
- Default: ``1`` (true)
+ on the port specified by the ``HTTPPort`` setting. Default: ``1`` (true)
``HTTPPort``:
The port the built-in HTTP server listens on. You can point a
browser to this port. Default: ``8080``.
+``EnableMonitor``:
+ Whether the application server should listen for monitor service requests.
+ Monitor is a minimal service that accepts a simple protocol and returns a
+ value indicating the status of the server. If you enable this, a separate
+ monitoring program such as ``Monitor.py`` can provide additional assurance
+ that the application server continues running at all times.
+ Default: ``0`` (false)
+``HTTPPort``:
+ The port the built-in HTTP server listens on. You can point a
+ browser to this port.
+``MonitorPort``:
+ The port for the monitor service. You cannot point a browser to this port.
+ You may wish to change this if you have another application running at this
+ port, or if you are running more than one AppServer. Default: ``8085``.
``PidFile``:
When the AppServer starts up, the process id will be written
into this file. The path will be relative to the working directory
@@ -407,3 +420,5 @@
``UseImportSpy`` to false, it resorts to polling. The polling interval
seconds can be set with the ``AutoReloadPollInterval`` setting which
defaults to 1 second.
+
+ By default, ``AutoReload`` is set to ``0`` (false).
Modified: Webware/trunk/WebKit/Docs/RelNotes-X.Y.phtml
==============================================================================
--- Webware/trunk/WebKit/Docs/RelNotes-X.Y.phtml (original)
+++ Webware/trunk/WebKit/Docs/RelNotes-X.Y.phtml Sat Apr 8 13:47:43 2006
@@ -21,7 +21,7 @@
demonstrating the use of Ajax with Webware for Python.
A baseclass <code>AjaxPage</code> and the necessary JavaScript
supporting these techniques are also included in the Examples context.
- (Thanks to John Dickinson and Robert Forkel.)</li>
+ (Thanks to John Dickinson and Robert Forkel.)</li>
</ul>
<a name="Improvements"></a><h2>Improvements and Refinements</h2>
@@ -30,17 +30,17 @@
to keep track of which modules have been imported. <code>ImportSpy</code>
was based on the old <code>ihooks</code> module which could raise problems
with other incompatible importing mechanisms like Cheetah templates or when
- using zipped Python eggs. This problem has been tackled from two sides,
- first by replacing ihooks with new (PEP 302) import hooks if available (they
- were implemented in Python 2.3), and second by allowing to suppress the use
- of <code>ImportSpy</code> completely by setting <code>UseImportSpy</code>
- to False in <span class="filename">AppServer.config</span>.
+ using zipped Python eggs. This problem has been tackled from two sides,
+ first by replacing ihooks with new (PEP 302) import hooks if available (they
+ were implemented in Python 2.3), and second by allowing to suppress the use
+ of <code>ImportSpy</code> completely by setting <code>UseImportSpy</code>
+ to False in <span class="filename">AppServer.config</span>.
In this case, <code>sys.modules</code> will be polled regularly.
The <code>ImportSpy</code> module now contains only the import hooks,
the rest of the functionality for tracking and managing concurrent import
has been sourced out to the new <code>ImportManager</code> module.</li>
<li>The start script for RedHat/Fedora Linux has been improved. A timing issue
- with the "restart" option has been solved.</li>
+ with the "restart" option has been solved (reported by Mike Trisko).</li>
</ul>
<a name="Security"></a><h2>Security</h2>
@@ -55,6 +55,9 @@
<a name="Bugfixes"></a><h2>Bugfixes</h2>
<ul>
+ <li>The <span class="filename">Monitor.py</span> for monitoring the
+ application server and the monitor service were broken and have been
+ fixed. You need to set <code>EnableMonitor</code> to use this.</li>
<li>Fixed bug in HTTP server that prevented multiple cookies from being
set at the same time.</li>
<li>Fixed a race condition in SessionStore (Ben Parker).</li>
Modified: Webware/trunk/WebKit/Monitor.py
==============================================================================
--- Webware/trunk/WebKit/Monitor.py (original)
+++ Webware/trunk/WebKit/Monitor.py Sat Apr 8 13:47:43 2006
@@ -2,7 +2,7 @@
"""Fault tolerance system for WebKit.
-:author: Jay Love
+Contributed to Webware for Python by Jay Love.
This module is intended to provide additional assurance that the
AppServer continues running at all times. This module will be
@@ -44,15 +44,15 @@
`defaultServer`:
default ``"ThreadedAppServer"``. The type of AppServer to start up
(as listed in ``Launch.py``)
-`checkInterval`:
+`monitorInterval`:
default 10. Seconds between checks.
`maxStartTime`:
- deafult 120. Seconds to wait for AppServer to start before killing
+ default 120. Seconds to wait for AppServer to start before killing
it and trying again.
"""
defaultServer = "ThreadedAppServer"
-checkInterval = 10 # add to config if this implementation is adopted
+monitorInterval = 10 # add to config if this implementation is adopted
maxStartTime = 120
import socket
@@ -90,27 +90,27 @@
import WebKit
code = 'from WebKit.%s import main' % serverName
exec code
- main(['monitor',])
+ main(['start'])
def startupCheck():
"""Make sure the AppServer starts up correctly."""
global debug
count = 0
print "Waiting for start..."
- time.sleep(checkInterval/2) #give the server a chance to start
+ time.sleep(monitorInterval/2) # give the server a chance to start
while 1:
if checkServer(0):
break
- count = count + checkInterval
+ count = count + monitorInterval
if count > maxStartTime:
print "Couldn't start AppServer."
print "Killing AppServer..."
- os.kill(srvpid,signal.SIGKILL)
+ os.kill(srvpid, signal.SIGKILL)
sys.exit(1)
print "Waiting for start..."
- time.sleep(checkInterval)
+ time.sleep(monitorInterval)
-def startServer(killcurrent = 1):
+def startServer(killcurrent=1):
"""Start the AppServer.
If `killcurrent` is true or not provided, kill the current AppServer.
@@ -120,16 +120,20 @@
global debug
if os.name == 'posix':
if killcurrent:
- try: os.kill(srvpid,signal.SIGTERM)
- except: pass
- try: os.waitpid(srvpid,0)
- except: pass
+ try:
+ os.kill(srvpid, signal.SIGTERM)
+ except:
+ pass
+ try:
+ os.waitpid(srvpid, 0)
+ except:
+ pass
srvpid = os.fork()
if srvpid == 0:
createServer(not killcurrent)
sys.exit()
-def checkServer(restart = 1):
+def checkServer(restart=1):
"""Send a check request to the AppServer.
If restart is 1, then attempt to restart the server
@@ -148,7 +152,7 @@
s.connect(addr)
s.send(statstr)
s.shutdown(1)
- resp = s.recv(9) #up to 1 billion requests!
+ resp = s.recv(9) # up to 1 billion requests!
monwait = time.time() - sts
if debug:
print "Processed %s Requests." % resp
@@ -176,7 +180,7 @@
running = 1
- file = open("monitorpid.txt","w")
+ file = open("monitorpid.txt", "w")
if os.name == 'posix':
file.write(str(os.getpid()))
file.flush()
@@ -189,8 +193,10 @@
if debug:
print "Startup check exception:", e
print "Exiting monitor..."
- try: os.kill(srvpid,signal.SIGTERM)
- except: pass
+ try:
+ os.kill(srvpid, signal.SIGTERM)
+ except:
+ pass
sys.exit()
while running:
@@ -198,17 +204,21 @@
if debug:
print "Checking server..."
checkServer()
- time.sleep(checkInterval)
+ time.sleep(monitorInterval)
except Exception, e:
if debug:
print "Exception:", e
if not running:
return
print "Exiting Monitor..."
- try: os.kill(srvpid,signal.SIGTERM)
- except: sys.exit(0)
- try: os.waitpid(srvpid,0) #prevent zombies
- except: sys.exit(0)
+ try:
+ os.kill(srvpid, signal.SIGTERM)
+ except:
+ sys.exit(0)
+ try:
+ os.waitpid(srvpid, 0) # prevent zombies
+ except:
+ sys.exit(0)
def shutDown(signum, frame):
@@ -253,9 +263,9 @@
(from the PID file ``monitorpid.txt``).
"""
- pid = int(open("monitorpid.txt","r").read())
+ pid = int(open("monitorpid.txt", "r").read())
# this goes to the other running instance of this module
- os.kill(pid,signal.SIGINT)
+ os.kill(pid, signal.SIGINT)
## Command line interface ##
@@ -311,16 +321,32 @@
print e
usage()
if not wwdir in sys.path:
- sys.path.insert(0,wwdir)
+ sys.path.insert(0, wwdir)
sys.path.remove('')
try:
sys.path.remove('.')
except:
pass
- cfg = open(os.path.join(wwdir,"WebKit","Configs/AppServer.config"))
- cfg = eval(cfg.read())
- addr = ((cfg['Host'],cfg['Port']-1))
+ cfgfile = open(os.path.join(wwdir, "WebKit",
+ "Configs/AppServer.config")).read()
+ cfg = { 'True': 1==1, 'False': 1==0, 'WebwarePath': wwdir }
+ if cfgfile.lstrip().startswith('{'):
+ cfg = eval(cfgfile, cfg)
+ else:
+ exec cfgfile in cfg
+ if not cfg.has_key('EnableMonitor') or not cfg['EnableMonitor']:
+ print "Monitoring has not been enabled in AppServer.config!"
+ sys.exit()
+ if cfg.has_key('Host'):
+ host = cfg['Host']
+ else:
+ host = '127.0.0.1'
+ if cfg.has_key('MonitorPort'):
+ port = cfg['MonitorPort']
+ else:
+ port = 8085
+ addr = (host, port)
if 'stop' in args:
stop()
Modified: Webware/trunk/WebKit/ThreadedAppServer.py
==============================================================================
--- Webware/trunk/WebKit/ThreadedAppServer.py (original)
+++ Webware/trunk/WebKit/ThreadedAppServer.py Sat Apr 8 13:47:43 2006
@@ -671,7 +671,7 @@
settingPrefix = 'Monitor'
def handleRequest(self):
- verbose = self.server._verbose
+ verbose = self._server._verbose
startTime = time.time()
if verbose:
print 'BEGIN REQUEST'
@@ -682,11 +682,11 @@
BUFSIZE = 8*1024
dict = self.receiveDict()
if dict['format'] == "STATUS":
- conn.send(str(self.server._requestID))
+ conn.send(str(self._server._requestID))
elif dict['format'] == 'QUIT':
conn.send("OK")
conn.close()
- self.server.shutDown()
+ self._server.shutDown()
from WebKit.ASStreamOut import ASStreamOut
@@ -802,7 +802,7 @@
def makeInput(self):
"""Create a file-like object from the socket."""
- return self._sock.makefile("rb",8012)
+ return self._sock.makefile("rb", 8012)
# Determines whether the main look should run in another thread.
# On Win NT/2K/XP, we run the mainloop in a different thread because
|