Commit d9409702 authored by Shane Hathaway's avatar Shane Hathaway

Simplified the way product refresh happens. Instead of using the reload()

function, we just remove the appropriate modules from sys.modules.  This
ensures that modules are loaded in the correct order.
parent 54b023a4
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
############################################################################## ##############################################################################
''' '''
Functions for refreshing products. Functions for refreshing products.
$Id: RefreshFuncs.py,v 1.1 2001/05/17 18:35:08 shane Exp $ $Id: RefreshFuncs.py,v 1.2 2001/08/06 15:04:52 shane Exp $
''' '''
import os, sys import os, sys
...@@ -182,55 +182,6 @@ def setDependentProducts(jar, productid, dep_ids): ...@@ -182,55 +182,6 @@ def setDependentProducts(jar, productid, dep_ids):
products[productid] = product = PersistentMapping() products[productid] = product = PersistentMapping()
product['dependent_products'] = tuple(map(str, dep_ids)) product['dependent_products'] = tuple(map(str, dep_ids))
# Functions for sorting modules by dependency.
def listRequiredModulesByClass(klass, rval):
if hasattr(klass, '__module__'):
rval[klass.__module__] = 1 # klass.__module__ is a string.
if hasattr(klass, '__bases__'):
for b in klass.__bases__:
listRequiredModulesByClass(b, rval)
def listRequiredModules(module):
rval = {}
if hasattr(module, '__dict__'):
for key, value in module.__dict__.items():
t = type(value)
if t in ClassTypes:
listRequiredModulesByClass(value, rval)
elif t is ModuleType and hasattr(value, '__name__'):
rval[value.__name__] = 1
elif t is FuncType and value.func_globals.has_key('__name__'):
rval[value.func_globals['__name__']] = 1
return rval
def sortModulesByDependency(modlist):
unchosen = {}
for name, module in modlist:
unchosen[name] = (module, listRequiredModules(module))
chose = 1
rval = []
while chose:
chose = 0
for name, (module, req) in unchosen.items():
all_satisfied = 1
for n in unchosen.keys():
if name == n:
continue # Skip self.
if req.has_key(n):
# There is still a dependency. Can't
# include this module in the list yet.
all_satisfied = 0
break
if all_satisfied:
chose = 1
rval.append((name, module))
del unchosen[name]
# There might be some modules left over that are interdependent.
for name, (module, req) in unchosen.items():
rval.append((name, module))
return rval
# Functions for performing refresh. # Functions for performing refresh.
...@@ -250,7 +201,7 @@ def listRefreshableModules(productid): ...@@ -250,7 +201,7 @@ def listRefreshableModules(productid):
for name, module in sys.modules.items(): for name, module in sys.modules.items():
if module and (name == prefix or name[:lpdot] == prefixdot): if module and (name == prefix or name[:lpdot] == prefixdot):
reload_var = getReloadVar(module) reload_var = getReloadVar(module)
if callable(reload_var) or reload_var: if reload_var:
rval.append((name, module)) rval.append((name, module))
return rval return rval
...@@ -276,33 +227,27 @@ def performRefresh(jar, productid): ...@@ -276,33 +227,27 @@ def performRefresh(jar, productid):
setupModTimes(productid) # Refresh again only if changed again. setupModTimes(productid) # Refresh again only if changed again.
modlist = listRefreshableModules(productid) modlist = listRefreshableModules(productid)
modlist = sortModulesByDependency(modlist) former_modules = {}
try:
for name, module in modlist: # Remove modules from sys.modules but keep a handle
# Remove the __import_error__ attribute. # on the old modules in case there's a problem.
try: del module.__import_error__ for name, module in modlist:
except: pass m = sys.modules.get(name, None)
# Ask the module how it should be reloaded. if m is not None:
reload_var = getReloadVar(module) former_modules[name] = m
if callable(reload_var): del sys.modules[name]
try:
reload_var() # Reimport and reinstall the product.
except: from OFS import Application
logBadRefresh(productid) Application.reimport_product(productid)
return 0 app = jar.root()['Application']
else: Application.reinstall_product(app, productid)
try: return 1
reload(module) except:
except: # Couldn't refresh. Reinstate removed modules.
logBadRefresh(productid) for name, module in former_modules.items():
return 0 sys.modules[name] = module
raise
# Reinitialize and reinstall the product.
from OFS import Application
Application.reimport_product(productid)
app = jar.root()['Application']
Application.reinstall_product(app, productid)
return 1
def performSafeRefresh(jar, productid): def performSafeRefresh(jar, productid):
try: try:
...@@ -316,6 +261,7 @@ def performSafeRefresh(jar, productid): ...@@ -316,6 +261,7 @@ def performSafeRefresh(jar, productid):
return 1 return 1
def performFullRefresh(jar, productid): def performFullRefresh(jar, productid):
# Refresh dependent products also.
if performSafeRefresh(jar, productid): if performSafeRefresh(jar, productid):
dep_ids = getDependentProducts(jar, productid) dep_ids = getDependentProducts(jar, productid)
for dep_id in dep_ids: for dep_id in dep_ids:
...@@ -412,6 +358,9 @@ def checkModTimes(productid): ...@@ -412,6 +358,9 @@ def checkModTimes(productid):
# Functions for performing auto-refresh. # Functions for performing auto-refresh.
def checkAutoRefresh(jar): def checkAutoRefresh(jar):
'''
Returns the IDs of products that need to be auto-refreshed.
'''
# Note: this function is NOT allowed to change the database! # Note: this function is NOT allowed to change the database!
global next_auto_refresh_check global next_auto_refresh_check
now = time() now = time()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment