[PEAK] issues with Trellis event loops and threads

Sergey Schetinin maluke at gmail.com
Tue Jul 22 12:27:05 EDT 2008


On Mon, Jul 21, 2008 at 19:14, Phillip J. Eby <pje at telecommunity.com> wrote:
> At 05:35 PM 7/21/2008 +0300, Sergey Schetinin wrote:
>>
>> Well, I get that, but I think that essentially, the only thing I need
>> is to have the same Time instance be the current in more than one
>> thread.
>
> Well, your thinking is wrong, then.  :)

I see how the problems could happen if the Trellis transactions don't
use locks, but that's easy enough to monkeypatch:

from __future__ import with_statement
from threading import Lock
from peak.rules import around
from peak.events.stm import Controller

trellis_lock = Lock()

@around(Controller._process.im_func)
def process(next_method, *args, **kw):
    with trellis_lock:
        return next_method(*args, **kw)



I tried to test if what I said initially will be at all true, and it
seems to be:


from peak.events.trellis import *
from peak.events.activity import *
from threading import *

class ThreadedComponent(Component):
    timer = attr(None)
    time_service = None

    @perform
    def rule(self):
        bool(self.timer)
        print 'rule ran in', currentThread().getName()

    def run(self):
        global Time
        Time <<= lambda: self.time_service
        self.timer = Time[1]


c = ThreadedComponent(time_service=Time.get())
th = Thread(target=c.run)

assert EventLoop._next_time is None
th.start()
th.join()
assert EventLoop._next_time is not None


So this seems to work. Any hints about what to look out for?



Also, I think I found a bug with the basic EventLoop implementation --
the main loop never exits if there were any events scheduled, test
case attached.


> ctx = State.get()
>
> #... new thread
>
> ctx.swap()
>
> Bear in mind, however, that doing this is an incredibly, horrifically bad
> idea  and you should never actually do it, because most services aren't
> going to be sharable across threads.  Really, you should explicitly share
> those services that need to be -- and CAN be -- shared across threads.

Well, the reason to use Contextual for me (apart from Trellis) is that
because the code that performs some actions doesn't know about all the
context that is required for the underlying operations (as there are
multiple backends), with Contextual it's possible, in a way, to pass
the parameters to code that will only be called some levels deeper
into the stack, and sometimes the call can happen in another thread.
Is that a misuse of the library or should I be safe as long as I only
use my own services in this way?

Thanks.


-- 
Best Regards,
Sergey Schetinin

http://s3bk.com/ -- S3 Backup
http://word-to-html.com/ -- Word to HTML Converter
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test_loop.py
Type: text/x-python
Size: 265 bytes
Desc: not available
Url : http://www.eby-sarna.com/pipermail/peak/attachments/20080722/5eb741d1/test_loop.py


More information about the PEAK mailing list