[mod_python] Circular references starting from the request objectare not collected

Nicolas Lehuen nicolas at lehuen.com
Thu Sep 9 22:01:23 EDT 2004


Jorey Bump wrote:

> Nicolas Lehuen wrote:
> 
> > def handler(req):
> >     # req.foobar=req
> 
> I'm not sure what you're doing, but won't that create a "hall 
> of mirrors" effect?
> 
>   req.foobar.foobar.foobar.foobar.foobar...
> 
> Wouldn't it be better to reset the attribute before storing req?
> 
>   req.foobar = []
>   req.foobar = req


No, you won't have a hall of mirror, just a reference loop. It's OK for the
Python interpreter, but it can only be cleaned up from memory if the garbage
collector is properly notified. It is for Python code but for native code,
you have to do the aforementionned tricks.

This was a dumb sample, just to show the problem with circular references. I
wrote a small mod_python.publisher clone, which does not have the annoying
bug with collision of module name, plus handle concurrent reloading of
published pages gracefully and so on. When it is stable enough, I think I'll
put it somewhere on the web. Anyway... In the handler, I decorate the
request object with many attributes, to make it a little bit more
object-oriented, like that :

def handler(req):
	req.external_redirect = lambda location, permanent=0, text=None:
util.redirect(req,location,permanent,text)

This way I can write :

return req.external_redirect('http://www.example.org/')

Which I find cleaner than
util.external_redirect(req,'http://www.example.org/') and symmetrical to
req.internal_redirect.

The problem is that defining this external_redirect creates an implicit
circular reference (due to nested scopes : req.external -> lambda -> req)...
Thus creating a memory leak.

There is a workaround, in fact, it is to make sure that all you reference
from the request object is deleted, by manually writing :

	del req.external_redirect

at the end of the handler. I'm going to try that right now (or just drop
this silly req.external_redirect idea...). But the trouble is that this bug
can bite you just about anytime, and you have to really think things through
to make sure that you don't create any circular reference. This is OK in the
framework, but the application writers won't like it.

Regards,

Nicolas




More information about the Mod_python mailing list