Author: chrisz
Date: Sun Jun 20 08:57:36 2010
New Revision: 8141
Modified:
Webware/trunk/WebKit/Configs/Application.config
Webware/trunk/WebKit/Docs/Configuration.txt
Webware/trunk/WebKit/Docs/RelNotes-X.Y.phtml
Webware/trunk/WebKit/ServletFactory.py
Log:
Introduced new ReloadServletClasses setting (see bug 3016673 reported by Patrick Gendron).
Modified: Webware/trunk/WebKit/Configs/Application.config
==============================================================================
--- Webware/trunk/WebKit/Configs/Application.config (original)
+++ Webware/trunk/WebKit/Configs/Application.config Sun Jun 20 08:57:36 2010
@@ -72,6 +72,8 @@
# Caching:
CacheServletClasses = True # set to False for debugging
CacheServletInstances = True # set to False for debugging
+ReloadServletClasses = True # set to True for quick and dirty reloading
+# Directory for storing compiled PSP and Kid templates:
CacheDir = 'Cache'
# Set to True to clear the PSP cache on disk when the AppServer starts:
ClearPSPCacheOnStart = False
Modified: Webware/trunk/WebKit/Docs/Configuration.txt
==============================================================================
--- Webware/trunk/WebKit/Docs/Configuration.txt (original)
+++ Webware/trunk/WebKit/Docs/Configuration.txt Sun Jun 20 08:57:36 2010
@@ -269,6 +269,18 @@
persist from one AppServer run to the next. If you have PSPs that
take a long time to compile, this can give a speedup. Default:
``False`` (cache will persist).
+``ReloadServletClasses``:
+ During development of an application, servlet classes will be changed
+ very frequently. The AutoReload mechanism could be used to detect such
+ changes and to reload modules with changed servlet classes, but it would
+ cause an app server restart every time a servlet class is changed. So
+ by default, modules with servlet classes are reloaded without restarting
+ the server. This can potentially cause problems when other modules are
+ dependent on the reloaded module because the dependent modules will not
+ be reloaded. To allow reloading only using the AutoReload mechanism,
+ you can set ``ReloadServletClasses`` to ``False`` in such cases. Default:
+ ``True`` (quick and dirty reloading).
+
Errors
------
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 Sun Jun 20 08:57:36 2010
@@ -25,6 +25,15 @@
<code>SilentURIs</code> you can specify request URIs for which you don't
want messages with request info to be printed in the server output.
By default, as earlier, all requests will appear in the server output.</li>
+ <li>Changes in servlet classes are not picked up using the AutoReload
+ mechanism; the corresponding modules are simply reloaded. However, this can
+ cause problems when other modules are dependent on the reloaded modules,
+ e.g. by inheriting from the reloaded servlet class. For such cases,
+ the new <span class="filename">Application.config</span> setting
+ <code>ReloadServletClasses</code>, when set to <code>False</code>, can be
+ used to suppress reloading of servlet classes and utilizing the AutoReload
+ mechanism for reloading the servlet classes instead (Bug 3016673 reported
+ by Patrick Gendron).</li>
</ul>
<a name="Improvements"></a><h2>Improvements and Refinements</h2>
Modified: Webware/trunk/WebKit/ServletFactory.py
==============================================================================
--- Webware/trunk/WebKit/ServletFactory.py (original)
+++ Webware/trunk/WebKit/ServletFactory.py Sun Jun 20 08:57:36 2010
@@ -45,6 +45,7 @@
self._imp = self._app._imp
self._cacheClasses = self._app.setting("CacheServletClasses", True)
self._cacheInstances = self._app.setting("CacheServletInstances", True)
+ self._reloadClasses = self._app.setting("ReloadServletClasses", True)
# All caches are keyed on the path.
# _classCache caches the servlet classes, in dictionaries
# with keys 'mtime' and 'class'. 'mtime' is the
@@ -122,16 +123,13 @@
# and give it a unique name:
if not fullname or not path.startswith(contextPath):
remainder = serverSidePathToImport
- fullmodname = remainder.replace(
+ fullname = remainder.replace(
'\\', '_').replace('/', '_').replace('.', '_')
- if debug:
- print __file__, ", fullmodname =", fullmodname
- modname = os.path.splitext(os.path.basename(
+ name = os.path.splitext(os.path.basename(
serverSidePathToImport))[0]
- fp, pathname, stuff = self._imp.find_module(modname,
- [os.path.dirname(serverSidePathToImport)])
- module = self._imp.load_module(fullmodname, fp, pathname, stuff)
- module.__donotreload__ = True
+ moduleDir = os.path.dirname(serverSidePathToImport)
+ module = self._importModuleFromDirectory(fullname, name,
+ moduleDir, forceReload=self._reloadClasses)
return module
# First, we'll import the context's package.
@@ -158,7 +156,7 @@
name = os.path.splitext(moduleFileName)[0]
fullname = '%s.%s' % (fullname, name)
module = self._importModuleFromDirectory(fullname, name,
- moduleDir, forceReload=True)
+ moduleDir, forceReload=self._reloadClasses)
return module
def _importModuleFromDirectory(self, fullModuleName, moduleName,
@@ -177,10 +175,9 @@
"""
if debug:
print __file__, fullModuleName, moduleName, directory
- if not forceReload:
- module = sys.modules.get(fullModuleName)
- if module is not None:
- return module
+ module = sys.modules.get(fullModuleName)
+ if module is not None and not forceReload:
+ return module
if isPackageDir:
# check if __init__.py is in the directory
packageDir = os.path.join(directory, moduleName)
@@ -195,7 +192,7 @@
file.close()
fp, pathname, stuff = self._imp.find_module(moduleName, [directory])
module = self._imp.load_module(fullModuleName, fp, pathname, stuff)
- module.__donotreload__ = True
+ module.__donotreload__ = self._reloadClasses
return module
def loadClass(self, transaction, path):
|