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 kamaelia@googlegroups.com To unsubscribe from this group, send email to kamaelia+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/kamaelia?hl=en -~----------~----~----~----~------~----~------~--~---