How to pass event results using implicite bridge?

39 views
Skip to first unread message

Mikołaj Olszewski

unread,
Jul 23, 2014, 3:51:19 PM7/23/14
to circuit...@googlegroups.com
Hi! I'm a circuits newbie user. This framework made on me a great impression as very well designed and easy to use. Big applause for all contributors!
After several attempts, hovewer, I'm stuck, probably because of my lack of experience with circuits or some concepts misunderstanding. But in turn...

1. I'd like to run every component in its own process - no problem, just use method start with link
2. I'd like to pass event from one component to another - it seems that feature is one way: from master to linked component, and one level: events do not propagate to component linked to component linked to master
3. I'd like to collect event results from all components in one place - it's not possible or I do something wrong...

Below is my example code and generated output:

Code

from os import getpid

from circuits import Component, Debugger, Event, Manager, Timer


class hello(Event):
    """hello Event"""

    success = True


class App(Component):

    def hello(self, name):
        if name != 'app':
            self.fire(hello('app'))
        return "Hello {0:s} from App! ({1:d})".format(name, getpid())

    def hello_success(self, evt, result):
        print("App: {0}".format(result))


class Sub1(Component):

    def hello(self, name):
        return "Hello {0:s} from Sub1! ({1:d})".format(name, getpid())

    def hello_success(self, evt, result):
        print("Sub1: {0}".format(result))


class Sub2(Component):

    def hello(self, name):
        return "Hello {0:s} from Sub2! ({1:d})".format(name, getpid())


class SubSub(Component):

    def hello(self, name):
        return "Hello {0:s} from SubSub! ({1:d})".format(name, getpid())


class Master(Component):

    def hello_success(self, evt, result):
        print("Master: {0}".format(result))


m = Master() + Debugger()
Timer(1, hello('master'), persist=True).register(m)
a = App()
a.start(process=True, link=m)
Sub1().start(process=True, link=m)
Sub2().start(process=True, link=m)
SubSub().start(process=True, link=a)
m.run()


Output

<registered[*] (<Debugger/* 9264:MainThread (queued=0) [S]>, <Master/* 9264:MainThread (queued=9) [R]> )>
<registered[b9e84339-7972-42b8-944b-29333df80540] (<UNIXClient/b9e84339-7972-42b8-944b-29333df80540 9264:MainThread (queued=0) [S]>, <Bridge/b9e84339-7972-42b8-944b-29333df80540 9264:MainThread (queued=0) [S]> )>
<registered[1fe40944-9ec9-4f6e-aac7-7daf3c9f7680] (<UNIXClient/1fe40944-9ec9-4f6e-aac7-7daf3c9f7680 9264:MainThread (queued=0) [S]>, <Bridge/1fe40944-9ec9-4f6e-aac7-7daf3c9f7680 9264:MainThread (queued=0) [S]> )>
<registered[*] (<Timer/* 9264:MainThread (queued=0) [S]>, <Master/* 9264:MainThread (queued=9) [R]> )>
<registered[360d3770-2545-4473-8669-79c1ab4feae2] (<UNIXClient/360d3770-2545-4473-8669-79c1ab4feae2 9264:MainThread (queued=0) [S]>, <Bridge/360d3770-2545-4473-8669-79c1ab4feae2 9264:MainThread (queued=0) [S]> )>
<registered[b9e84339-7972-42b8-944b-29333df80540] (<Bridge/b9e84339-7972-42b8-944b-29333df80540 9264:MainThread (queued=0) [S]>, <Master/* 9264:MainThread (queued=8) [R]> )>
<registered[360d3770-2545-4473-8669-79c1ab4feae2] (<Bridge/360d3770-2545-4473-8669-79c1ab4feae2 9264:MainThread (queued=0) [S]>, <Master/* 9264:MainThread (queued=7) [R]> )>
<registered[1fe40944-9ec9-4f6e-aac7-7daf3c9f7680] (<Bridge/1fe40944-9ec9-4f6e-aac7-7daf3c9f7680 9264:MainThread (queued=0) [S]>, <Master/* 9264:MainThread (queued=6) [R]> )>
<started[*] (<Master/* 9264:MainThread (queued=5) [R]> )>
<registered[select] (<Select/select 9264:MainThread (queued=0) [S]>, <UNIXClient/b9e84339-7972-42b8-944b-29333df80540 9264:MainThread (queued=0) [S]> )>
<ready[b9e84339-7972-42b8-944b-29333df80540] (<UNIXClient/b9e84339-7972-42b8-944b-29333df80540 9264:MainThread (queued=0) [S]> )>
<ready[1fe40944-9ec9-4f6e-aac7-7daf3c9f7680] (<UNIXClient/1fe40944-9ec9-4f6e-aac7-7daf3c9f7680 9264:MainThread (queued=0) [S]> )>
<ready[360d3770-2545-4473-8669-79c1ab4feae2] (<UNIXClient/360d3770-2545-4473-8669-79c1ab4feae2 9264:MainThread (queued=0) [S]> )>
<hello[*] ('master' )>
<hello_success[*] (<hello[*] ('master' )>, None )>
<_write[360d3770-2545-4473-8669-79c1ab4feae2] (<socket.socket fd=8, family=AddressFamily.AF_UNIX, type=2049, proto=0> )>
<_write[b9e84339-7972-42b8-944b-29333df80540] (<socket.socket fd=5, family=AddressFamily.AF_UNIX, type=2049, proto=0> )>
<_write[1fe40944-9ec9-4f6e-aac7-7daf3c9f7680] (<socket.socket fd=11, family=AddressFamily.AF_UNIX, type=2049, proto=0> )>
Master: None
App: Hello master from App! (9266)
Sub1: Hello master from Sub1! (9268)
App: Hello app from App! (9266)
<_read[b9e84339-7972-42b8-944b-29333df80540] (<socket.socket fd=5, family=AddressFamily.AF_UNIX, type=2049, proto=0> )>
<read[b9e84339-7972-42b8-944b-29333df80540] (b'\x80\x03\x8a\x08\x9eg\xfd\xe2\xfc\x07\x00\x80c__main__\nhello\nq\x00)\x81q\x01}q\x02(X\x07\x00\x00\x00stoppedq\x03\x89X\x08\x00\x00\x00channelsq\x04X\x01\x00\x00\x00*q\x05\x85q\x06X\t\x00\x00\x00cancelledq\x07\x89X\x05\x00\x00\x00valueq\x08ccircuits.core.values\nValue\nq\t)\x81q\n}q\x0b(X\x06\x00\x00\x00parentq\x0ch\nX\x07\x00\x00\x00handledq\r\x89X\x05\x00\x00\x00eventq\x0eh\x01X\x06\x00\x00\x00resultq\x0f\x89X\x07\x00\x00\x00promiseq\x10\x89X\x06\x00\x00\x00_valueq\x11NX\x06\x00\x00\x00notifyq\x12\x89X\x06\x00\x00\x00errorsq\x13\x89ubh\x12X\r\x00\x00\x00value_changedq\x14X\x03\x00\x00\x00uidq\x15NX\x06\x00\x00\x00kwargsq\x16}q\x17X\x04\x00\x00\x00argsq\x18]q\x19X\x03\x00\x00\x00appq\x1aaX\x04\x00\x00\x00nameq\x1bX\x05\x00\x00\x00helloq\x1cub\x86q\x1d.\x80\x03\x8a\x06\x16\xcf,\xe3\xfc\x07ccircuits.core.values\nValue\nq\x00)\x81q\x01}q\x02(X\x06\x00\x00\x00parentq\x03h\x01X\x07\x00\x00\x00handledq\x04\x89X\x05\x00\x00\x00eventq\x05c__main__\nhello\nq\x06)\x81q\x07}q\x08(X\x05\x00\x00\x00valueq\th\x01X\x07\x00\x00\x00stoppedq\n\x89X\x04\x00\x00\x00nameq\x0bX\x05\x00\x00\x00helloq\x0cX\t\x00\x00\x00cancelledq\r\x89X\x04\x00\x00\x00argsq\x0e]q\x0fX\x06\x00\x00\x00masterq\x10aX\x06\x00\x00\x00notifyq\x11X\r\x00\x00\x00value_changedq\x12X\x03\x00\x00\x00uidq\x13NX\x06\x00\x00\x00kwargsq\x14}q\x15X\x06\x00\x00\x00remoteq\x16\x88X\x08\x00\x00\x00channelsq\x17X\x01\x00\x00\x00*q\x18\x85q\x19ubX\x06\x00\x00\x00resultq\x1a\x88X\x07\x00\x00\x00promiseq\x1b\x89X\x06\x00\x00\x00_valueq\x1cX\x1d\x00\x00\x00Hello master from App! (9266)q\x1dX\x06\x00\x00\x00notifyq\x1e\x89X\x06\x00\x00\x00errorsq\x1f\x89ub\x86q .' )>
<_read[360d3770-2545-4473-8669-79c1ab4feae2] (<socket.socket fd=8, family=AddressFamily.AF_UNIX, type=2049, proto=0> )>
<read[360d3770-2545-4473-8669-79c1ab4feae2] (b'\x80\x03\x8a\x06\x16\xcf,\xe3\xfc\x07ccircuits.core.values\nValue\nq\x00)\x81q\x01}q\x02(X\x06\x00\x00\x00parentq\x03h\x01X\x07\x00\x00\x00handledq\x04\x89X\x05\x00\x00\x00eventq\x05c__main__\nhello\nq\x06)\x81q\x07}q\x08(X\x05\x00\x00\x00valueq\th\x01X\x07\x00\x00\x00stoppedq\n\x89X\x04\x00\x00\x00nameq\x0bX\x05\x00\x00\x00helloq\x0cX\t\x00\x00\x00cancelledq\r\x89X\x04\x00\x00\x00argsq\x0e]q\x0fX\x06\x00\x00\x00masterq\x10aX\x06\x00\x00\x00notifyq\x11X\r\x00\x00\x00value_changedq\x12X\x03\x00\x00\x00uidq\x13NX\x06\x00\x00\x00kwargsq\x14}q\x15X\x06\x00\x00\x00remoteq\x16\x88X\x08\x00\x00\x00channelsq\x17X\x01\x00\x00\x00*q\x18\x85q\x19ubX\x06\x00\x00\x00resultq\x1a\x88X\x07\x00\x00\x00promiseq\x1b\x89X\x06\x00\x00\x00_valueq\x1cX\x1e\x00\x00\x00Hello master from Sub1! (9268)q\x1dX\x06\x00\x00\x00notifyq\x1e\x89X\x06\x00\x00\x00errorsq\x1f\x89ub\x86q .' )>
<_read[1fe40944-9ec9-4f6e-aac7-7daf3c9f7680] (<socket.socket fd=11, family=AddressFamily.AF_UNIX, type=2049, proto=0> )>
<read[1fe40944-9ec9-4f6e-aac7-7daf3c9f7680] (b'\x80\x03\x8a\x06\x16\xcf,\xe3\xfc\x07ccircuits.core.values\nValue\nq\x00)\x81q\x01}q\x02(X\x06\x00\x00\x00parentq\x03h\x01X\x07\x00\x00\x00handledq\x04\x89X\x05\x00\x00\x00eventq\x05c__main__\nhello\nq\x06)\x81q\x07}q\x08(X\x05\x00\x00\x00valueq\th\x01X\x07\x00\x00\x00stoppedq\n\x89X\x04\x00\x00\x00nameq\x0bX\x05\x00\x00\x00helloq\x0cX\t\x00\x00\x00cancelledq\r\x89X\x04\x00\x00\x00argsq\x0e]q\x0fX\x06\x00\x00\x00masterq\x10aX\x06\x00\x00\x00notifyq\x11X\r\x00\x00\x00value_changedq\x12X\x03\x00\x00\x00uidq\x13NX\x06\x00\x00\x00kwargsq\x14}q\x15X\x06\x00\x00\x00remoteq\x16\x88X\x08\x00\x00\x00channelsq\x17X\x01\x00\x00\x00*q\x18\x85q\x19ubX\x06\x00\x00\x00resultq\x1a\x88X\x07\x00\x00\x00promiseq\x1b\x89X\x06\x00\x00\x00_valueq\x1cX\x1e\x00\x00\x00Hello master from Sub2! (9270)q\x1dX\x06\x00\x00\x00notifyq\x1e\x89X\x06\x00\x00\x00errorsq\x1f\x89ub\x86q .' )>
<hello[*] ('master' )>
Master: None
<hello_success[*] (<hello[*] ('master' )>, None )>
Sub1: Hello master from Sub1! (9268)
<_write[360d3770-2545-4473-8669-79c1ab4feae2] (<socket.socket fd=8, family=AddressFamily.AF_UNIX, type=2049, proto=0> )>
App: Hello master from App! (9266)
<_write[b9e84339-7972-42b8-944b-29333df80540] (<socket.socket fd=5, family=AddressFamily.AF_UNIX, type=2049, proto=0> )>
App: Hello app from App! (9266)
<_write[1fe40944-9ec9-4f6e-aac7-7daf3c9f7680] (<socket.socket fd=11, family=AddressFamily.AF_UNIX, type=2049, proto=0> )>
<_read[360d3770-2545-4473-8669-79c1ab4feae2] (<socket.socket fd=8, family=AddressFamily.AF_UNIX, type=2049, proto=0> )>
<read[360d3770-2545-4473-8669-79c1ab4feae2] (b'\x80\x03\x8a\x06\x16\xcf,\xe3\xfc\x07ccircuits.core.values\nValue\nq\x00)\x81q\x01}q\x02(X\x06\x00\x00\x00parentq\x03h\x01X\x07\x00\x00\x00handledq\x04\x89X\x05\x00\x00\x00eventq\x05c__main__\nhello\nq\x06)\x81q\x07}q\x08(X\x05\x00\x00\x00valueq\th\x01X\x07\x00\x00\x00stoppedq\n\x89X\x04\x00\x00\x00nameq\x0bX\x05\x00\x00\x00helloq\x0cX\t\x00\x00\x00cancelledq\r\x89X\x04\x00\x00\x00argsq\x0e]q\x0fX\x06\x00\x00\x00masterq\x10aX\x06\x00\x00\x00notifyq\x11X\r\x00\x00\x00value_changedq\x12X\x03\x00\x00\x00uidq\x13NX\x06\x00\x00\x00kwargsq\x14}q\x15X\x06\x00\x00\x00remoteq\x16\x88X\x08\x00\x00\x00channelsq\x17X\x01\x00\x00\x00*q\x18\x85q\x19ubX\x06\x00\x00\x00resultq\x1a\x88X\x07\x00\x00\x00promiseq\x1b\x89X\x06\x00\x00\x00_valueq\x1cX\x1e\x00\x00\x00Hello master from Sub1! (9268)q\x1dX\x06\x00\x00\x00notifyq\x1e\x89X\x06\x00\x00\x00errorsq\x1f\x89ub\x86q .' )>
<_read[b9e84339-7972-42b8-944b-29333df80540] (<socket.socket fd=5, family=AddressFamily.AF_UNIX, type=2049, proto=0> )>
<_read[1fe40944-9ec9-4f6e-aac7-7daf3c9f7680] (<socket.socket fd=11, family=AddressFamily.AF_UNIX, type=2049, proto=0> )>
<read[b9e84339-7972-42b8-944b-29333df80540] (b'\x80\x03\x8a\x06qo\xfd\xe2\xfc\x07c__main__\nhello\nq\x00)\x81q\x01}q\x02(X\x07\x00\x00\x00stoppedq\x03\x89X\x08\x00\x00\x00channelsq\x04X\x01\x00\x00\x00*q\x05\x85q\x06X\t\x00\x00\x00cancelledq\x07\x89X\x05\x00\x00\x00valueq\x08ccircuits.core.values\nValue\nq\t)\x81q\n}q\x0b(X\x06\x00\x00\x00parentq\x0ch\nX\x07\x00\x00\x00handledq\r\x89X\x05\x00\x00\x00eventq\x0eh\x01X\x06\x00\x00\x00resultq\x0f\x89X\x07\x00\x00\x00promiseq\x10\x89X\x06\x00\x00\x00_valueq\x11NX\x06\x00\x00\x00notifyq\x12\x89X\x06\x00\x00\x00errorsq\x13\x89ubh\x12X\r\x00\x00\x00value_changedq\x14X\x03\x00\x00\x00uidq\x15NX\x06\x00\x00\x00kwargsq\x16}q\x17X\x04\x00\x00\x00argsq\x18]q\x19X\x03\x00\x00\x00appq\x1aaX\x04\x00\x00\x00nameq\x1bX\x05\x00\x00\x00helloq\x1cub\x86q\x1d.\x80\x03\x8a\x06\x16\xcf,\xe3\xfc\x07ccircuits.core.values\nValue\nq\x00)\x81q\x01}q\x02(X\x06\x00\x00\x00parentq\x03h\x01X\x07\x00\x00\x00handledq\x04\x89X\x05\x00\x00\x00eventq\x05c__main__\nhello\nq\x06)\x81q\x07}q\x08(X\x05\x00\x00\x00valueq\th\x01X\x07\x00\x00\x00stoppedq\n\x89X\x04\x00\x00\x00nameq\x0bX\x05\x00\x00\x00helloq\x0cX\t\x00\x00\x00cancelledq\r\x89X\x04\x00\x00\x00argsq\x0e]q\x0fX\x06\x00\x00\x00masterq\x10aX\x06\x00\x00\x00notifyq\x11X\r\x00\x00\x00value_changedq\x12X\x03\x00\x00\x00uidq\x13NX\x06\x00\x00\x00kwargsq\x14}q\x15X\x06\x00\x00\x00remoteq\x16\x88X\x08\x00\x00\x00channelsq\x17X\x01\x00\x00\x00*q\x18\x85q\x19ubX\x06\x00\x00\x00resultq\x1a\x88X\x07\x00\x00\x00promiseq\x1b\x89X\x06\x00\x00\x00_valueq\x1cX\x1d\x00\x00\x00Hello master from App! (9266)q\x1dX\x06\x00\x00\x00notifyq\x1e\x89X\x06\x00\x00\x00errorsq\x1f\x89ub\x86q .' )>
<read[1fe40944-9ec9-4f6e-aac7-7daf3c9f7680] (b'\x80\x03\x8a\x06\x16\xcf,\xe3\xfc\x07ccircuits.core.values\nValue\nq\x00)\x81q\x01}q\x02(X\x06\x00\x00\x00parentq\x03h\x01X\x07\x00\x00\x00handledq\x04\x89X\x05\x00\x00\x00eventq\x05c__main__\nhello\nq\x06)\x81q\x07}q\x08(X\x05\x00\x00\x00valueq\th\x01X\x07\x00\x00\x00stoppedq\n\x89X\x04\x00\x00\x00nameq\x0bX\x05\x00\x00\x00helloq\x0cX\t\x00\x00\x00cancelledq\r\x89X\x04\x00\x00\x00argsq\x0e]q\x0fX\x06\x00\x00\x00masterq\x10aX\x06\x00\x00\x00notifyq\x11X\r\x00\x00\x00value_changedq\x12X\x03\x00\x00\x00uidq\x13NX\x06\x00\x00\x00kwargsq\x14}q\x15X\x06\x00\x00\x00remoteq\x16\x88X\x08\x00\x00\x00channelsq\x17X\x01\x00\x00\x00*q\x18\x85q\x19ubX\x06\x00\x00\x00resultq\x1a\x88X\x07\x00\x00\x00promiseq\x1b\x89X\x06\x00\x00\x00_valueq\x1cX\x1e\x00\x00\x00Hello master from Sub2! (9270)q\x1dX\x06\x00\x00\x00notifyq\x1e\x89X\x06\x00\x00\x00errorsq\x1f\x89ub\x86q .' )>
Master: None
App: Hello master from App! (9266)
App: Hello app from App! (9266)
Sub1: Hello master from Sub1! (9268)

I'd be very thankful for some help.

--
Mikołaj Olszewski

James Mills

unread,
Jul 23, 2014, 5:14:02 PM7/23/14
to circuit...@googlegroups.com
Hi! Welcome to circuits :)

Based on what you're described, your code and sample output (Thank you!)
I think there are two things:

1. We probably need to improve Bridge for this use-case and possibly add an extra kwarg to .start() so we can name the "bridge link".
2. Or explicitly use circuits.node which lets you have a bit more control but you'd be doing the linking between processes yourself.

If I have time I'll try to write a simple example demonstrating 2)

Thanks!

cheers
James

--
You received this message because you are subscribed to the Google Groups "circuits" group.
To unsubscribe from this group and stop receiving emails from it, send an email to circuits-user...@googlegroups.com.
To post to this group, send email to circuit...@googlegroups.com.
Visit this group at http://groups.google.com/group/circuits-users.
For more options, visit https://groups.google.com/d/optout.

Mikołaj Olszewski

unread,
Jul 24, 2014, 5:20:03 AM7/24/14
to circuit...@googlegroups.com
W dniu środa, 23 lipca 2014 23:14:02 UTC+2 użytkownik James Mills napisał:
Hi! Welcome to circuits :)

Thanks, and thanks for a quick answer. :)
 

Based on what you're described, your code and sample output (Thank you!)
I think there are two things:

1. We probably need to improve Bridge for this use-case and possibly add an extra kwarg to .start() so we can name the "bridge link".

Hm, I have to admit I'm a little bit confused... Am I correct that event propagation is one way and one level only? Am I correct it is not possible to collect results from event handlers in different processes?

 
2. Or explicitly use circuits.node which lets you have a bit more control but you'd be doing the linking between processes yourself.


Nodes are more flexible but also more complicated to use (custom interprocess link) and less efficient (communication is via UDP and normal sockets instead of noproto and unix sockets in case of bridge) so IMHO bridge is the better solution for one machine.

--
Mikołaj Olszewski

James Mills

unread,
Jul 24, 2014, 7:25:55 AM7/24/14
to circuit...@googlegroups.com
Yeah Bridge just wasn't designed for this particular use- case...

But I see no reason why it can't be adapted for this.

Send us a pull request to make Bridge better :)

ceers
James

--

Mikołaj Olszewski

unread,
Jul 25, 2014, 8:11:13 AM7/25/14
to circuit...@googlegroups.com

W dniu czwartek, 24 lipca 2014 13:25:55 UTC+2 użytkownik James Mills napisał:
Yeah Bridge just wasn't designed for this particular use- case...

Ok, thanks for explanation.
 
But I see no reason why it can't be adapted for this.

Send us a pull request to make Bridge better :)

If I only knew how to stop return form event handler _on_event in brige until recieve information about complete the execution of event handler in the second process... Maybe something similar to method wait should be done but I cannot recognize what is needed to do to wait for value_changed from remote component in a proper way.

--
Mikołaj Olszewski

James Mills

unread,
Aug 6, 2014, 12:26:13 PM8/6/14
to circuit...@googlegroups.com
Hi Mikołaj,

Sorry for the delayed response. I've been a bit busy lately
with PyConAU and my new Job. I presented circuits
at PyConAU 2014!

Have you made any progress with what you're after?

I've been thinking about your use-case I think still think it's
very doable.

cheers
James

--

Mikołaj Olszewski

unread,
Aug 13, 2014, 7:08:54 AM8/13/14
to circuit...@googlegroups.com

W dniu środa, 6 sierpnia 2014 18:26:13 UTC+2 użytkownik James Mills napisał:
Hi Mikołaj,

Sorry for the delayed response. I've been a bit busy lately
with PyConAU and my new Job. I presented circuits
at PyConAU 2014!

No problem. :)
 

Have you made any progress with what you're after? (...)


For me as a newbie it is not a piece of cake to change that code without any advice or clue. So I went on vacation and now I'm trying do it in other way.

Unfortunately I found another problem - I cannot get proper result value form event in wich I call other event using yield and self.call. Sample code is as follows:


from circuits import Event, Component, Debugger


class test(Event):

    success = True
    complete = True


class other(Event):
    pass


class App(Component):

    def started(self, parent):
        self.fire(test())

    def test(self):
        result = yield self.call(other())
        return result

    def other(self):
        return 'ok'


(App() + Debugger()).run()



and logs:

<registered[*] (<Debugger/* 10134:MainThread (queued=0) [S]>, <App/* 10134:MainThread (queued=2) [R]> )>
<started[*] (<App/* 10134:MainThread (queued=1) [R]> )>
<test[*] ( )>
<other[*] ( )>
<other_done[*] ('ok' )>
<test_success[*] (<test[*] ( )>, None )>
<test_complete[*] (<test[*] ( )>, None )>


As you can see value passed to *_success and *_complete is None instead of 'ok'. Is this correct behaviour?

--
Mikołaj Olszewski


James Mills

unread,
Aug 13, 2014, 7:32:49 AM8/13/14
to circuit...@googlegroups.com
What version of Python are you using with circuits? And what version of circuits?

I have an initial issue with your code:

$ python test.py 
  File "test.py", line 21
    return result
SyntaxError: 'return' with argument inside generator


Here is my corrected version:

#!/usr/bin/env python


from __future__ import print_function


from circuits import Event, Component, Debugger


class test(Event):

    success = True
    complete = True


class other(Event):
    pass


class App(Component):

    def started(self, parent):
        self.fire(test())

    def test(self):
        result = yield self.call(other())
        yield result

    def other(self):
        return 'ok'


(App() + Debugger()).run()

And the output:

$ python test.py 
<registered[*] (<Debugger/* 27527:MainThread (queued=0) [S]>, <App/* 27527:MainThread (queued=2) [R]> )>
<started[*] (<App/* 27527:MainThread (queued=1) [R]> )>
<test[*] ( )>
<other[*] ( )>
<other_done[*] ('ok' )>
<test_success[*] (<test[*] ( )>, 'ok' )>
<test_complete[*] (<test[*] ( )>, 'ok' )>
^C<signal[*] (2, <frame object at 0x814c20> )>
<stopped[*] (<App/* 27527:MainThread (queued=0) [S]> )>


As you can see it is as you expected.

Python 2.7.8 with circuits 3.0.0.dev (from dev)

cheers
James

Mikołaj Olszewski

unread,
Aug 13, 2014, 8:40:11 AM8/13/14
to circuit...@googlegroups.com


W dniu środa, 13 sierpnia 2014 13:32:49 UTC+2 użytkownik James Mills napisał:
What version of Python are you using with circuits? And what version of circuits?


python 3.4, circuits 3.0.0.dev
 
(..)

Here is my corrected version:

Indeed, changing return to yield solves the problem.

Let's complicate example a little bit... :)


from circuits import Event, Component, Debugger, task, Worker



class test(Event):

    success = True
    complete = True


def other():
    return 'ok'


def another():
    return 'yay'


class App(Component):

    def init(self):
        Worker(process=True).register(self)


    def started(self, parent):
        self.fire(test())

    def test(self):
        result = yield self.call(task(other))
        yield result



class Sub(Component):

    def test(self):
        result = yield self.call(task(another))
        yield result



(App() + Sub() + Debugger()).run()



produce:


<registered[worker] (<Worker/worker 12169:MainThread (queued=0) [S]>, <App/* 12169:MainThread (queued=4) [R]> )>
<registered[*] (<Sub/* 12169:MainThread (queued=0) [S]>, <App/* 12169:MainThread (queued=3) [R]> )>
<registered[*] (<Debugger/* 12169:MainThread (queued=0) [S]>, <App/* 12169:MainThread (queued=2) [R]> )>
<started[*] (<App/* 12169:MainThread (queued=1) [R]> )>
<test[*] ( )>
<task[*] (<function another at 0x7f947b0a9488> )>
<task[*] (<function other at 0x7f947b0d9b70> )>
<task_success[*] (<task[*] (<function other at 0x7f947b0d9b70> )>, 'ok' )>
<task_done[*] ('yay' )>
<task_success[*] (<task[*] (<function another at 0x7f947b0a9488> )>, 'yay' )>
<test_success[*] (<test[*] ( )>, [<Value ('yay') result: True errors: False for <task[*] (<function another at 0x7f947b0a9488> )>, <Value ('yay') result: True errors: False for <task[*] (<function another at 0x7f947b0a9488> )>] )>
<test_complete[*] (<test[*] ( )>, [<Value ('yay') result: True errors: False for <task[*] (<function another at 0x7f947b0a9488> )>, <Value ('yay') result: True errors: False for <task[*] (<function another at 0x7f947b0a9488> )>] )>



The result is unexpected - last task value is doubled but first one is lost.

--
Mikołaj Olszewski

Mikołaj Olszewski

unread,
Aug 13, 2014, 9:48:39 AM8/13/14
to circuit...@googlegroups.com
The workaround is to use event value explicite, i.e. instead of

def test(self):
        result = yield self.call(task(other))
        yield result.value


just use

def test(self):
        evt = task(other)
        yield self.call(evt)
        yield evt.value.value



There is another issue with Timer - using following code

import time

from circuits import Event, Component, Debugger, task, Worker, Timer



class test(Event):

    success = True
    complete = True


def other():
    time.sleep(1)
    return 'ok'


def another():
    time.sleep(3)

    return 'yay'


class App(Component):

    def init(self):
        Worker(process=True).register(self)

    def started(self, parent):
        Timer(1, test()).register(self)

    def test(self):
        evt = task(other)
        yield self.call(evt)
        yield evt.value.value


class Sub(Component):

    def test(self):
        evt = task(another)
        yield self.call(evt)
        yield evt.value.value



(App() + Sub() + Debugger()).run()


I get

registered[worker] (<Worker/worker 14749:MainThread (queued=0) [S]>, <App/* 14749:MainThread (queued=4) [R]> )>
<registered[*] (<Sub/* 14749:MainThread (queued=0) [S]>, <App/* 14749:MainThread (queued=3) [R]> )>
<registered[*] (<Debugger/* 14749:MainThread (queued=0) [S]>, <App/* 14749:MainThread (queued=2) [R]> )>
<started[*] (<App/* 14749:MainThread (queued=1) [R]> )>
<registered[*] (<Timer/* 14749:MainThread (queued=0) [S]>, <App/* 14749:MainThread (queued=1) [R]> )>
<test[*] ( )>
<prepare_unregister[*] (<Timer/* 14749:MainThread (queued=0) [S]> )>
<prepare_unregister_complete[<Timer/* 14749:MainThread (queued=0) [S]>] (<prepare_unregister[*] (<Timer/* 14749:MainThread (queued=0) [S]> )>, None )>
<task[*] (<function other at 0x7f82a54dbb70> )>
<task[*] (<function another at 0x7f82a54ab488> )>
<unregistered[*] (<Timer/* 14749:MainThread (queued=0) [S]>, <App/* 14749:MainThread (queued=1) [R]> )>
<task_done[*] ('ok' )>
<task_success[*] (<task[*] (<function other at 0x7f82a54dbb70> )>, 'ok' )>
<test_success[*] (<test[*] ( )>, 'ok' )>
<test_complete[*] (<test[*] ( )>, 'ok' )>
<task_success[*] (<task[*] (<function another at 0x7f82a54ab488> )>, 'yay' )>


so just first task is included as a value in test_success and test_complete.

--
Mikołaj Olszewski

James Mills

unread,
Aug 13, 2014, 5:10:10 PM8/13/14
to circuit...@googlegroups.com
Are we not tracking task events and their values properly?

cheers
James

James Mills

unread,
Aug 13, 2014, 5:11:23 PM8/13/14
to circuit...@googlegroups.com
Hmm let me play with these samples a bit more.
We should fix this :)

cheers
James

--

Mikołaj Olszewski

unread,
Aug 18, 2014, 5:44:08 PM8/18/14
to circuit...@googlegroups.com


W dniu środa, 13 sierpnia 2014 23:11:23 UTC+2 użytkownik James Mills napisał:
Hmm let me play with these samples a bit more.
We should fix this :)

Hi James,
have you seen what is going on?

--
Mikołaj Olszewski

James Mills

unread,
Aug 18, 2014, 5:57:28 PM8/18/14
to circuit...@googlegroups.com

Hmmm I see. Seems like were not collecting the results of coros properly. I'll do some testing...

--

Mikołaj Olszewski

unread,
Sep 1, 2014, 6:00:11 PM9/1/14
to circuit...@googlegroups.com
Ok, I have returned to my original problem and after several trials I probably found the solution. I'll make a PR.

James Mills

unread,
Sep 1, 2014, 6:01:25 PM9/1/14
to circuit...@googlegroups.com

Oh great news! Thank you!

Reply all
Reply to author
Forward
0 new messages