Graham Dumpleton
grahamd at dscpl.com.au
Thu Oct 14 17:21:52 EDT 2004
On Oct 14 14:51, "Nicolas Lehuen" <nicolas at lehuen.com> wrote: > > Subject: RE: [mod_python] Udate python modules without restarting Apache > > This __clone__() method is a very neat idea indeed ! For the moment I prefer > not to keep any data between reloads (what needs to be kept is in the > database), but there may be occurrences where such a mechanisms would be > handy. The actual data may be in the database, but if one is using a database connection pooling object, one has to keep that somewhere. That is one candidate for types of objects that you may want to preserve across a reload and not simply throw away. > Right now I'm trying to use imp.new_module but I get curious results... > Apparently some classes that are imported from other modules are redefined > even though they should not. The net result is that some isinstance() tests > fail where they should not (reminds me of ClassLoader problems in Java). I > tried to build a simple test case exhibiting the problem, but it does not. > What's for sure, is that when I do : > > exec source in module.__dict__ > > If module is a fake module object (a place holder class Module(object): > pass), all my code is OK. If it is a real module, I get weird behaviours. > I'm still investigating on the subject. Reloading of modules can always be a problem when one is comparing the type of objects as you have to be careful that something hasn't stashed away a copy of an older class object for type comparison, or conversly is using a newer version of the class object to check the type of an object created from the older instance. This was one of the issues that originally came up in prior email, specifically the Servlet class from mpservlets. In that case it was because a module was being imported using "import" in one place and "apache.import_module()" in another. As such there were two actual instances of the Servlet class and comparing the type of an instance based on one against the other class type was going to fail. The problem can still arise even when one consistently uses a module import and caching mechanism, as such mechanisms typically only look at the highest level import and not any sub imports that may have been done by the object. Thus, you can have stale copies of modules still in memory until the appropriate parent module is also reloaded, flushing out the stale sub module. BTW, the __clone__() method could also be conceivably used to copy across classes as opposed to instances of classes. You might therefore have something like: def __clone__(module): module.Interface = Interface if not globals().has_key("Interface"): class Interface: def method(self,object): pass class Implementation(Interface): def method(self,object): if isinstance(object,Interface): ... That is, have a simple class definition which defines the interface, much like interface objects in Java. Have the actual implementation derive from that. In code create instances of the Implementation, but when doing isinstance() checks, compare it to the Interface base class. Thus, the Interface class definition is always the same actual class type object because it is preserved across reloads. Although the derived class may be called Implementation in every version of the module, it is actually a different class type object in memory. To compare types of Implementation objects is not going to work if instances are based on different versions, but if your check is for them being a derived instance of Interface, you woud be okay. Although for a robust system that can easily be updated if necessary without restarting Apache you could go to this extent, I frankly doubt many, if any at all would bother to do so. I will be interested to here what is causing your problem in case there is something I have missed about how this stuff operates. -- Graham Dumpleton (grahamd at dscpl.com.au)
|