views:

195

answers:

3

Hi,

Context: Imagine that you have a standard CherryPy hello word app:

   def index(self):
      return "Hello world!"
   index.exposed = True

and you would like to do some post-processing, i.e. record request processing or just log the fact that we were called from specific IP. What you would do is probably:

def index(self):
   self.RunMyPostProcessing()
   return "Hello world!"
index.exposed = True

However, that will add to your request processing time. (btw. And probably you will use decorators, or even some more sophisticated method if you would like to call it on every function).

Question: Is there a way of creating a global threading aware queue (buffer) to which each request can write messages (events) that needs be logged, while some magic function will grab it and post-process? Would you know a pattern for such a thing?

I bet that CherryPy supports something like that :-)

Thank you in advance...

+1  A: 

An on_end_request custom tool may be what you want.

Martin v. Löwis
+4  A: 

The "global threading aware queue" is called Queue.Queue. I just added a recipe for this at http://tools.cherrypy.org/wiki/BackgroundTaskQueue

fumanchu
Are you reading in my mind (my code) or what? ;-))Thank you so much, it was exactly the sort of solution I was looking for.
stic
A: 

How to tie together Martin v. Löwis' and fumanchu's answers? Or are they alternatives that should be separate?

Well, for me fumanchu solution is exactly what I was looking for. In each method I would like to have a possibility to decide what should be logged (i.e. at login page I would look for IP / cookies / sessions etc., while on some pages I really need to know how long it takes to generate a page).However, nothing will stop you from writing to log in a method that would be registered as on_end_request handler.
stic
Martin's approach would work, and would move the processing time to a point after the response has been written out to the client. However, it would still tie up that thread for a while, leaving it unavailable to serve new requests, particularly subsequent requests on the same conn. By moving the processing to another thread, we can avoid that problem.
fumanchu