[Zope3-Users] Threads and transactions

Tom Dossis td at yoma.com.au
Tue Dec 14 15:22:40 EST 2004


Alberto Degli Esposti wrote:
> Hi,
>  I have an application that needs to start some independent threads as
> a consequence of a user request. For example, user submits a list of
> files in a form, an utility uses a thread to do a checksum on each
> file (very large files) then, when finished, sets the result as
> annotation to an object. I think that each thread needs his own
> transaction (or his own db connection) but the
> db/connection/transaction API is not clear for me and I haven't found
> the correct way to follow yet. I saw that I can subscribe the
> IDataBaseOpenedEvent to get a db reference to initialize the utility,
> but for some reasons this is not a good solution for my app. Can
> someone help me please?
> 

Sounds like what you want to do could be useful in general...
Process a user request which fires off a "background" task inside Zope.

Zope's ThreadedTaskDispatcher provides task management for the zope app 
server(s).  It could be useful to have access to it, but I don't think 
it's exposed, or I can't figure out how to get it.

Anyway, I've written a simple test which 'hacks' zope to get access to 
the task_dispatcher.

Setup a user form which invokes runTask.  The user response is 
immediate, but you should see the print out of MyTask on your console 
(providing you're running in debug mode).

 From the user form, you can invoke runTask serval times and you'll
notice the user response will pause once the thread pool is exhausted.

You can configure the thread pool size in zope.conf.  Also I'd expect 
each task to have it's own zodb transaction / thread context.


Example...

def runTask(self, task):
     # ** NOTE **
     # this requires a hack in zope.app.server.main.setup(), ie.
     # taskDispatcher = None
     # def setup(...
     #    ...
     #    global taskDispatcher
     #    taskDispatcher = task_dispatcher

     from zope.app.server.main import taskDispatcher
     taskDispatcher.addTask(MyTask())


import time
from zope.interface import implements
from zope.server.interfaces import ITask

class MyTask(object):
     implements(ITask)

     def service(self):
         ID = id(self)
         for i in range(10):
             print 'MyTask.service(%s)' % ID
             time.sleep(1)

     def cancel(self):
         print 'MyTask.cancel()'

     def defer(self):
         print 'MyTask.defer()'


More information about the Zope3-users mailing list