On Friday 13 November 2009 04:36:56 Jim Burnes wrote:
> Good luck and let us know how it works. It sounds like a good idea. The
> objects encapsulate all their state, components press the button methods
> and events are pushed down the pipeline.
I've not had a chance for detailed comment, but two brief comments:
* Yes, sending components through Axon/Kamaelia pipelines does already
happen. (Indeed, we'll often send around ("inbox", component) pairs
because that's defined as a service.
Components that send components through inboxes include the TCP
subsystem and pygame subsystem.
Python-Axon pipelines are fully polymorphic, and as you suspected, fun.
It's possible that typed inboxes may be useful though, but that's a
different discussion.
* If you pass in-active/passive objects - ie not components and not
microprocesses - through the pipeline, because they don't have a local
thread of control, this is generally thread safe.
After all, when you put an object in an outbox, you no longer own it,
and if you take something from an inbox you own it. This ensures the
idea of single reader/single writer for any single piece of data, which
eliminates whole classes of concurrency bugs. (You don't necessarily
make a system much simpler, but you at least you know one sort of bug
doesn't exist, and one that's normally awkward to sort out/find :-)
BUT, if you put a component in the pipeline, you need to be careful.
Specifically, this means a component is expecting a component on an
inbox. In that case, your recipient component cannot know in advance
whether the recipient is a generator-type component, threaded component,
or similar. (eg a generator inside a threaded chassis, which has been
proposed)
This means the instant you start calling methods on components rather
than sending them messages, you have to start thinking about thread
safety. Now, if you're doing "read only", and not worried about the data
going stale, that's one way of dealing with it. (I'm actually doing this
in a project at the moment :-) that I can't really talk about
publically )-:
Picking a neutral example though if you had a component that kept track
of a piece of information that changes often - such as directory size,
the current time, how many users are connected, then that's probably OK.
If you do need to change the component's state in some fashion though you
have an issue. For example if you do this:
somecomponent.somestore.append(something)
And in its thread of control "somecomponent" does this in a loop: (say)
self.somestore = []
You have a clear issue depending on ordering of instructions.
There are two ways round this:
* Build something actor like based on threadsafe queues. This is what
the scheduler does incidentally for handling .activate() calls in
a threadsafe manner. ie accept the call, append the request to an
inbound queue, and then inside the component's main thread service
these calls there. (This cries out for decorator support :-)
* The other is to use the STM code, which is probably far more better
suited to this sort of task. http://www.kamaelia.org/STM describes
it, but effectively you do this:
1 Create an STM store.
2 Allocate some names in it
3 Grab a checkout containing those names/values
4 Update the values in that checkout
5 Check in/commit those values
6 If you get a conflict, go back to 4
ie the same as databases or version control (sans versions)
Bottom line really:
* If possible send passive objects.
* If sending components, ideally the safest way of dealing with them is to
create a link to the component (using self.link) from a local outbox,
send a message to it and get a message back. (by telling it where to
respond to.)
eg: (for one offs)
somecomponent = self.recv("somebox")
link = self.link((self,"adhoc"), (somecomponent, "inbox"))
self.send( { "req" : "some request",
"callback" : (self, "someinbox") }, "adhoc")
self.unlink(link)
(Incidentally in Axon2 I'm planning on calling this "post" :-)
* If that's inappropriate for whatever reason, you need to consider
threadsafety, at that point, seriously consider using the STM code -
it's what it's there for.
* Finally, consider building something actor-like on top. Everyone who's
built a mini-axon has actually built something actor-like, so this
shouldn't be that bad, but there's no real direct support for ad-hoc
actor like stuff as yet.
* If you're merely reading values via a method call, that's fine.
(Consider reading your balance at a cashpoint - that's generally OK :)
However like the cashpoint analogy you have to assume that the value
can change between you reading it and you using it. Using that value as
the basis for an update is unsafe - for the reasons given in many many
many books & talks on this :-)
[Incidentally Jim, I suspect you may be aware of these issues, but I'm also
aware that the thread is archived, and may be read in future :-) ]
> I still think that you may need some sort of "bus" or "kernel" object for
> mailbox creation, but that may be a orthogonal issue.
That's the purpose behind adaptive comms components really - since they can
all create mailboxes.
Interestingly, whilst we don't do this in Kamaelia/Axon, MASCOT's equivalents
to out inboxes/outboxes can exist independently of what we call components.
It may be that upgrading inboxes/outboxes to fully fledged things may have
some benefits.
For example, if I could send you a box that I allow you to share, it would
provide an interesting means of creating a thread pool. (At present the way
to do that really would be to send a Queue.Queue through a pipeline, and
allow the recipients to all read from it, but that's a different
conversation :-)
Regards,
Michael.
--
http://yeoldeclue.com/blog
http://twitter.com/kamaelian
http://www.kamaelia.org/Home
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"kamaelia" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/kamaelia?hl=en
-~----------~----~----~----~------~----~------~--~---