does circuits fit my usage scenario? I've done a lot of python, but no circuits

34 views
Skip to first unread message

jimmy

unread,
Jul 1, 2015, 5:06:38 PM7/1/15
to circuit...@googlegroups.com
What I have in  mind is a program consisting of a number of activities. Some of these activities will start only after other activities have finished. I thought I might use circuits as the notification mechanism. Let's say that activity C should start only after activities A and B have finished. It looks like I would need an element that is told when activity A finishes, is told when activity B finishes, and then fires off activity C. This looks like the sort of thing that circuits is made for.

I've looked at some of the tutorials and haven't seen a class that fills that particular need: collecting notifications and then firing off activities once it has collected a complete set. It doesn't look hard to write, but I wouldn't want to do that if it's already there in the framework.

Maybe there's a small example somewhere?


thanks

James Mills

unread,
Jul 1, 2015, 5:12:43 PM7/1/15
to circuit...@googlegroups.com
HI Jimmy and welcome to circuits!

Is circuits the best fit for your use-case? It can be! :)

Yes; circuits is very much event-driven, so anything you can model
with events circuits is awsome for! What you've described
is a sequence of events that depend on each other.

Whilst we don't have a builtin Component that does exactly
the sequence of events you describe; it would not be that
hard to write one -- And you could contribute it!

I'll be happy to write a quick example of your contrived example hwoever.

I'll write a proper one later today; but it would look something like:

def foo(self):
    self.call(a())  # synchronously fire and wait for a to complete
    self.call(b())  # synchronously fire and wait for b to complete
    self.fire(c())  # fire off asynchronous event c

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.

James B. Wilkinson

unread,
Jul 1, 2015, 5:44:36 PM7/1/15
to circuit...@googlegroups.com
> HI Jimmy and welcome to circuits!

thanks

> Whilst we don't have a builtin Component that does exactly
> the sequence of events you describe;

so I don’t have to feel bad about not finding one

> it would not be that
> hard to write one -- And you could contribute it!

happy to, if I end up with something I’m pleased with

> def foo(self):
> self.call(a()) # synchronously fire and wait for a to complete
> self.call(b()) # synchronously fire and wait for b to complete
> self.fire(c()) # fire off asynchronous event c

except that I’d like A and B to run concurrently, not one after the other. (My first use is a simple animation.) I think that where circuits comes in is that there is no guarantee as to which will finish first or how long it will take.

What I was thinking to do if there isn’t already something like this is to fire off A and B, collect notifications of completion in a set, and fire off C once the set is complete (in this case containing both A and B).

It looks like I would need a Process class to implement the activities, and a class named, say, Director to collect notifications and start new Processes.

In more detail: the starting event would fire A and B; each of these, on completion, would fire a termination event, the Director would collect these and fire off C once it has both. Does this sound like the way to do it?

BTW, it’s already working without circuits. I thought this would be a good project for a rewrite using circuits just to learn the framework. As of now, I know next to nothing and just don’t want to go off in the wrong direction and do something totally unidiomatic.

In the meantime, I’ll do some more reading.

thanks

James Mills

unread,
Jul 1, 2015, 7:17:44 PM7/1/15
to circuit...@googlegroups.com
On Thu, Jul 2, 2015 at 7:44 AM, James B. Wilkinson <the...@twc.com> wrote:
> def foo(self):
>     self.call(a())  # synchronously fire and wait for a to complete
>     self.call(b())  # synchronously fire and wait for b to complete
>     self.fire(c())  # fire off asynchronous event c

except that I’d like A and B to run concurrently, not one after the other. (My first use is a simple animation.) I think that where circuits comes in is that there is no guarantee as to which will finish first or how long it will take.

This is a common source of misinterpretation. Do you mean  A and B run in parallel? (Quite different to concurrent!)


What I was thinking to do if there isn’t already something like this is to fire off A and B, collect notifications of completion in a set, and fire off C once the set is complete (in this case containing both A and B).

So you can also take advantage of "feedback events" here.

e.g:

class a(Event):
    """a Event"""

    complete = True

When you self.fire(a()) -- When it completes you'll get an event triggered called a_complete
 

It looks like I would need a Process class to implement the activities, and a class named, say, Director to collect notifications and start new Processes.

So we have a Worker() component that wraps around multiprocessing.Pool for running tasks in parallel; you can use call/wait to coordinate and synchronize several or more tasks. 



In more detail: the starting event would fire A and B; each of these, on completion, would fire a termination event, the Director would collect these and fire off C once it has both. Does this sound like the way to do it?

Definitely possible to do :)


BTW, it’s already working without circuits. I thought this would be a good project for a rewrite using circuits just to learn the framework. As of now, I know next to nothing and just don’t want to go off in the wrong direction and do something totally unidiomatic.

A few questions:

Is this up somewhere and small enough to see what's going on from the code?
Does it spawn processes for the A & B tasks?
What is the overall purpose of the application?

cheers
James

James B. Wilkinson

unread,
Jul 1, 2015, 8:19:01 PM7/1/15
to circuit...@googlegroups.com
In the example below (from the Events section of the user manual) I wonder whether the line
result = [result]   shouldn’t be
result += [result]
#!/usr/bin/env python

from circuits import Component, Debugger, Event


class Identify(Event):

    """Identify Event"""

    success = True


class Pound(Component):

    def __init__(self):
        super(Pound, self).__init__()

        Debugger().register(self)
        Bob().register(self)
        Fred().register(self)

    def started(self, *args):
        self.fire(Identify())

    def Identify_success(self, evt, result):
        if not isinstance(result, list):
            result = [result]
        print "In pound:"
        for name in result:
            print name


class Dog(Component):

    def Identify(self):
        return self.__class__.__name__


class Bob(Dog):

    """Bob"""


class Fred(Dog):

    """Fred"""

Pound().run()

James Mills

unread,
Jul 1, 2015, 8:35:40 PM7/1/15
to circuit...@googlegroups.com
On Thu, Jul 2, 2015 at 10:18 AM, James B. Wilkinson <the...@twc.com> wrote:
In the example below (from the Events section of the user manual) I wonder whether the line
result = [result]   shouldn’t be

No this is definitely correct. This contrived tutorial is a working example :)
 
Basically what happens here is if you fire an event A
and you want feedback on that event (e.g: A_success or A_complete)
you will get multiple values if multiple event handlers handled A

e.g:

x = self.fire(a())

x.result can be a list of values or a scalar value

Hope this helps clear that up!

James B. Wilkinson

unread,
Jul 1, 2015, 11:12:32 PM7/1/15
to circuit...@googlegroups.com
No this is definitely correct. This contrived tutorial is a working example :)

Duh. You are going to laugh your ass off. I’ve obviously been staring at this screen too long. I saw that "result = [result]" is indented and immediately saw the whole two-line phrase as the standard list-accumulation loop. Never mind that it’s an if, not a loop, and never mind that that requires different variables on the two sides of the "=".

So am I correct in saying that that bit is there just in case there’s only one dog in the pound because result wouldn’t be a list then?


Let me try again: should the line of text right before this code example say Identify_success instead of identify_success?


One other thing: how does the Identify event know to signal success after it has been handled twice? Does it poke around in the registration information looking for items that have the correct handler? I ask because it looks like I could use the Event itself as my Director, particularly if I can put my own code in there to record the replies.


thanks for your patience

James Mills

unread,
Jul 1, 2015, 11:18:42 PM7/1/15
to circuit...@googlegroups.com
On Thu, Jul 2, 2015 at 1:12 PM, James B. Wilkinson <the...@twc.com> wrote:
No this is definitely correct. This contrived tutorial is a working example :)

Duh. You are going to laugh your ass off. I’ve obviously been staring at this screen too long. I saw that "result = [result]" is indented and immediately saw the whole two-line phrase as the standard list-accumulation loop. Never mind that it’s an if, not a loop, and never mind that that requires different variables on the two sides of the "=".

So am I correct in saying that that bit is there just in case there’s only one dog in the pound because result wouldn’t be a list then?

Yes precisely :)
 


Let me try again: should the line of text right before this code example say Identify_success instead of identify_success?


One other thing: how does the Identify event know to signal success after it has been handled twice? Does it poke around in the registration information looking for items that have the correct handler? I ask because it looks like I could use the Event itself as my Director, particularly if I can put my own code in there to record the replies.

Okay so clearly the documentation is a bit out-of-date and needs some updating.

I'll add a task/issue to get this done ASAP.

Basically some time ago (I'd have to check the ChangeLog/ReleaseNote)
we decided to make everything consistent. Basically:

* all event objects and their event names are case senseitive
* all event objects used within circuits itself are all lowercase

So this actually means the documentation and examples
you've been reading should read:

identify and identify_success

cheers
James

James B. Wilkinson

unread,
Jul 2, 2015, 2:28:13 AM7/2/15
to circuit...@googlegroups.com
On Jul 1, 2015, at 7:17 PM, James Mills <prol...@shortcircuit.net.au> wrote:

On Thu, Jul 2, 2015 at 7:44 AM, James B. Wilkinson <the...@twc.com> wrote:
> def foo(self):
>     self.call(a())  # synchronously fire and wait for a to complete
>     self.call(b())  # synchronously fire and wait for b to complete
>     self.fire(c())  # fire off asynchronous event c

except that I’d like A and B to run concurrently, not one after the other. (My first use is a simple animation.) I think that where circuits comes in is that there is no guarantee as to which will finish first or how long it will take.

This is a common source of misinterpretation. Do you mean  A and B run in parallel? (Quite different to concurrent!)

I don’t think so. It runs on a single cpu. I don’t see using the word “parallel” when that’s sthe case. On the other hand, since there’s just one thread, “concurrent” doesn’t fit that well, either. How about “simultaneously”? In any case, I was thinking more of the dictionary definition than the technical term when I said “concurrently”. I’ll have to double check with our OS guy, if he’s in town.

class a(Event):
    """a Event"""

    complete = True

Somewhere in the docs it will tell me the difference between success and complete? Or maybe it’s just that complete can be true when success is false because of an error.


So we have a Worker() component that wraps around multiprocessing.Pool for running tasks in parallel; you can use call/wait to coordinate and synchronize several or more tasks. 


mañana


Is this up somewhere and small enough to see what's going on from the code?

It’s about 250 lines of code, attached herewith. In the neighborhood of line 160 is the move method. It moves the object a couple of pixels and schedules itself to run again after a couple of milliseconds. That’s how the interleaving of A and B is all in one thread.

At line 210 ff. is the code that starts it going. The start method takes a parameter that is a function to run when it finishes. It runs A, then B, then resets itself and runs A and B simultaneously. Then it resets to the initial state and stops. That code is in the termination methods that get passed to the start method on the various times that it gets called.

Does it spawn processes for the A & B tasks?

No it’s all in one process.

What is the overall purpose of the application?

It’s a classroom demo for my class in computer organization. The full program (which I didn’t send yet) shows a model of a simplified MIPS cpu. Numbers from the register file travel to the alu and get combined (add, sub, ...) into a single number that then travels back around and gets written into a register. What I sent you is just the traveling part with a silly proof-of-concept demo tacked onto the end as main(). The advantage is that all you need is that one file, python3 and tkinter. And you don’t have to look at all the crazy code that hooks the reusable pieces together visually. I thought about learning enough Alice to do it, but our Alice chick said to do it in python.


crawler.py

James B. Wilkinson

unread,
Jul 2, 2015, 2:31:32 AM7/2/15
to circuit...@googlegroups.com
One other thing: how does the Identify event know to signal success after it has been handled twice? How does it know not to wait on some more dogs to bark?


I ask because it looks like I could use the Event itself as my Director, particularly if I can put my own code in there to record the replies.



thanks

James Mills

unread,
Jul 2, 2015, 5:17:50 AM7/2/15
to circuit...@googlegroups.com
On Thu, Jul 2, 2015 at 4:28 PM, James B. Wilkinson <the...@twc.com> wrote:
I don’t think so. It runs on a single cpu. I don’t see using the word “parallel” when that’s sthe case. On the other hand, since there’s just one thread, “concurrent” doesn’t fit that well, either. How about “simultaneously”? In any case, I was thinking more of the dictionary definition than the technical term when I said “concurrently”. I’ll have to double check with our OS guy, if he’s in town.

So yeah I go by the wikipedia definitions and come from a software engineering background
and so in circuits we define:

concurrency -- handling multiple things sequentially
parallel - handling multiple things simultaneously

circuits is by design a concurrency framework
but also supports many forms of parlallelism
and even distributed computing.

Make sense?
 

class a(Event):
    """a Event"""

    complete = True

Somewhere in the docs it will tell me the difference between success and complete? Or maybe it’s just that complete can be true when success is false because of an error.

Yes absolutely it does:

See:


It's kind of an advanced topic I guess; but we could
expand on the initial piece of documentation around it.
 


So we have a Worker() component that wraps around multiprocessing.Pool for running tasks in parallel; you can use call/wait to coordinate and synchronize several or more tasks. 


mañana

Huh?
 


Is this up somewhere and small enough to see what's going on from the code?

It’s about 250 lines of code, attached herewith. In the neighborhood of line 160 is the move method. It moves the object a couple of pixels and schedules itself to run again after a couple of milliseconds. That’s how the interleaving of A and B is all in one thread.

At line 210 ff. is the code that starts it going. The start method takes a parameter that is a function to run when it finishes. It runs A, then B, then resets itself and runs A and B simultaneously. Then it resets to the initial state and stops. That code is in the termination methods that get passed to the start method on the various times that it gets called.

Ahh thanks for this! And thanks for the explanations.
I'll take a look at this and have a play and let yyou know what I think
in terms of how you'd do this with circuits!
 

Does it spawn processes for the A & B tasks?

No it’s all in one process.

Okay; so therefore you really do mean concurrenct then :)

Because threads (*at least in CPython*) do *NOT* run in parallel or take advantage of multiple cores.
 

What is the overall purpose of the application?

It’s a classroom demo for my class in computer organization. The full program (which I didn’t send yet) shows a model of a simplified MIPS cpu. Numbers from the register file travel to the alu and get combined (add, sub, ...) into a single number that then travels back around and gets written into a register. What I sent you is just the traveling part with a silly proof-of-concept demo tacked onto the end as main(). The advantage is that all you need is that one file, python3 and tkinter. And you don’t have to look at all the crazy code that hooks the reusable pieces together visually. I thought about learning enough Alice to do it, but our Alice chick said to do it in python.

Ahh I see. You're in academia! Great! So am i (or trying to be!)

What you've described is actually a really good use-case/fit for circuits.
I'd love to see someone with more experience in CPU/Machine
simulation(s) build such a thing in circuits!

You *could* even simulate multiple CPU(s)/Cores
by taking advantage of circuits builtin IPC/Bridge

cheers
James

James Mills

unread,
Jul 2, 2015, 5:22:15 AM7/2/15
to circuit...@googlegroups.com
On Thu, Jul 2, 2015 at 4:31 PM, James B. Wilkinson <the...@twc.com> wrote:
One other thing: how does the Identify event know to signal success after it has been handled twice? How does it know not to wait on some more dogs to bark?


I ask because it looks like I could use the Event itself as my Director, particularly if I can put my own code in there to record the replies.

Does this answer your question?


cheers
James
Reply all
Reply to author
Forward
0 new messages