Hi All, I would like to do some bookkeeping *after* an object has been published, i.e. imagine a request is done for: /a/b/c/d 'b' is the (folderish) object that does the accounting, 'd' is the object to be published. I would like 'b' to examine the RESPONSE after publishing. I know there's a __before_publishing_traverse__, however, this is not what I want. Does someone know a way to implement this cleanly? I.e. without monkeypatching 'd' (which can be any kind of zope object)? Regards, Ivo -- Drs. I.R. van der Wijk -=- Brouwersgracht 132 Amaze Internet Services V.O.F. 1013 HA Amsterdam, NL -=- Tel: +31-20-4688336 Linux/Web/Zope/SQL/MMBase Fax: +31-20-4688337 Network Solutions Web: http://www.amaze.nl/ Consultancy Email: ivo@amaze.nl -=-
On Mon, 15 Apr 2002 15:05:32 +0200, Ivo van der Wijk <ivo@amaze.nl> wrote:
I would like to do some bookkeeping *after* an object has been published,
The transation object lets you register methods to be called on transaction commit, abort, etc. Toby Dickenson tdickenson@geminidataloggers.com
Ivo van der Wijk wrote:
Hi All,
I would like to do some bookkeeping *after* an object has been published, i.e. imagine a request is done for:
/a/b/c/d
'b' is the (folderish) object that does the accounting, 'd' is the object to be published. I would like 'b' to examine the RESPONSE after publishing.
I know there's a __before_publishing_traverse__, however, this is not what I want.
Does someone know a way to implement this cleanly? I.e. without monkeypatching 'd' (which can be any kind of zope object)?
REQUEST._hold() is designed for this purpose. _hold() accepts an object which will be deleted when the request is finished. Add an object with a __del__() method that calls your application logic. In fact, this is the mechanism Zope uses to make sure the database connection gets closed. (see ZODB/ZApplication.py.) Shane
Shane Hathaway wrote:
a __del__() method that calls your application logic. In fact, this is the mechanism Zope uses to make sure the database connection gets closed. (see ZODB/ZApplication.py.)
Ewww... ;-) Chris - Someone got some deodorant for ZApplication? ...sure *gets can with "Zope 3" written on side*
The request object has a hold area which keeps objects alive as long as the request lives. Although I have not tried it, you might be able to add an object to this hold area using __bobo_traverse__ defined on B. This object's class would need to have a destructor method (__del__) defined so that it can do something when the request is over and the response has presumably been written. you could code that something like this: In b's class: class b: ... def __bobo_traverse__(self, name): self.REQUEST._hold(ResponseChecker(self.REQUEST.RESPONSE)) class ResponseChecker: def __init__(self, response): self.response = response def __del__(self): ...do something with self.response... Like I said, I've never tried this, but you never know, it might work. If not, another option would be to have b use __bobo_traverse__ to dynamically add a destructor to the RESPONSE object (it doesn't already have one AFAIK). Like this: class b: ... def __bobo_traverse__(self, name): self.REQUEST.RESPONSE.__del__ = afterResponse def afterResponse(self): ...do something with response... The latter is a monkey patch, but a very narrow one, since the hook would only get put in for objects under an instance of b. -Casey Ivo van der Wijk wrote:
Hi All,
I would like to do some bookkeeping *after* an object has been published, i.e. imagine a request is done for:
/a/b/c/d
'b' is the (folderish) object that does the accounting, 'd' is the object to be published. I would like 'b' to examine the RESPONSE after publishing.
I know there's a __before_publishing_traverse__, however, this is not what I want.
Does someone know a way to implement this cleanly? I.e. without monkeypatching 'd' (which can be any kind of zope object)?
Regards,
Ivo
On Mon, Apr 15, 2002 at 09:39:47AM -0600, Casey Duncan wrote:
The request object has a hold area which keeps objects alive as long as the request lives. Although I have not tried it, you might be able to add an object to this hold area using __bobo_traverse__ defined on B.
This object's class would need to have a destructor method (__del__) defined so that it can do something when the request is over and the response has presumably been written.
you could code that something like this:
In b's class:
class b: ... def __bobo_traverse__(self, name): self.REQUEST._hold(ResponseChecker(self.REQUEST.RESPONSE))
class ResponseChecker: def __init__(self, response): self.response = response
def __del__(self): ...do something with self.response...
Like I said, I've never tried this, but you never know, it might work. If not, another option would be to have b use __bobo_traverse__ to dynamically add a destructor to the RESPONSE object (it doesn't already have one AFAIK). Like this:
This indeed does work. The only difference is that I'm installing the hook in __before_publishing_traverse__, so I don't have to do any traversal myself. I find it a scary solution though (though not as scary as monkeypatching __del__), so I'm not 100% sure if I will use this code, or perhaps I'll make it very optional (basically, thanks to this nice hack, QuotaFolder can do traffic accounting as well :) Cheers, Ivo -- Drs. I.R. van der Wijk -=- Brouwersgracht 132 Amaze Internet Services V.O.F. 1013 HA Amsterdam, NL -=- Tel: +31-20-4688336 Linux/Web/Zope/SQL/MMBase Fax: +31-20-4688337 Network Solutions Web: http://www.amaze.nl/ Consultancy Email: ivo@amaze.nl -=-
Ivo van der Wijk wrote: [snip]
This indeed does work. The only difference is that I'm installing the hook in __before_publishing_traverse__, so I don't have to do any traversal myself.
I find it a scary solution though (though not as scary as monkeypatching __del__), so I'm not 100% sure if I will use this code, or perhaps I'll make it very optional (basically, thanks to this nice hack, QuotaFolder can do traffic accounting as well :)
I'll agree that dynamically creating __del__ methods might be a bit scary, but I don't see anything too crazy about this method, depending of course on exactly what you are doing with RESPONSE. ;^) You're really just calling something at the last possible second before the REQUEST goes away. -Casey
participants (5)
-
Casey Duncan -
Chris Withers -
Ivo van der Wijk -
Shane Hathaway -
Toby Dickenson