
scott <scottw <at> qbik.com> writes:
On Behalf Of Darryl Green
I've tended to think of the tightly/early bound, just queue a functor, and the message passsing + switch case as 2 completely independent patterns, but maybe they should be built on a common framework (at a level above the detail that they both ivolve queuing some sort of object).
Yes. I agree with your distinguishing of the two forms. There is some relief to be found in that.
While I can acknowledge the existence of async messaging where the sender has type knowledge of the receiver, I also think its dangerous.
In what way do you think it is dangerous? Provided that the type knowledge is correct, then it merely provides an assurance to the sender (which they may or may not care about) that the recipient claims to deal with a particular type of message. (and a small opportunity for optimisation based on the type knowledge)
Given the two approaches, most developers head down the "fake method" route. This inevitably results in receipient-type knowledge and that precludes some really cool active objects (please refer to other messages if this fails to allude to anything).
Are you referring to the 'forwarding proxy' example (proxy in an object sense, not a method sense)? This could be done with a method interface, but it would a maintenance nightmare :) Actually, I think this could be done, but in a different way to the message-only version. An object of the proxied type would still have its method stubs invoked to create fully-bound functor messages, but those messages would be queued to a different object - the one that would forward these (essentially typeless) messages on to the real object recipient. The difference would be in the proxies - they would bind to member function addresses, but not on the current instance, and they would enqueue the message to a non-local queue.
Also I think its right to say that there is nothing method-based that cant be done message- based; but is the converse true?
Given that messages would provide the implementation of the method emulation, I agree. I suspect the converse may be true, but it might take a lot of (unrewarded) effort...
There is some more fundamental reason why message-based is right that is probably rooted in theory (sets?). There has to be good reason why protocols are so "right". Everyone appreciates the content of RFCs and telephony signaling specifications but we persist with method-based messaging.
But a method-based interface would still be implemented as message-passing. How can an underlying mechanism have fundamental advantages over something which is layered above it?
<sigh> Its an area of personal wonder.
The AO pattern doesn't require that you identify the object you want to invoke the method on in the proxy, because you send the proxy to that object, and only that object. So one could drop the "this" parameter from the proxy. That would potentially allow the proxy to be routed/forwarded in a more general reactive object model (I think this was one of Scotts requirements)?
I don't think that I've really followed this. The active object pattern specifies that there may be many identical servants servicing method requests concurrently, but this implies that the servants can't be stateful. I think this is a special case, as far as rective objects are concerned.
I'm not 100% sure how useful this is, but it might be nice for the class of problem where you do want concurrent execution - of as many completely independent instances of the object as is "useful". The client/master doesn't care which instance - the next available one will do nicely.
IIUC, this is a de-generate form of interaction that has been touched on previously. At least in my work it imposes an unacceptable design constraint; there needs to be some identification of the receiving active object. Most significantly (?) there could not be multiple servants per scheduler (i.e. thread).
is. Perhaps its interface can be made more generic to allow its operation to be policy based. Broadening the definition from "return value" to "message delivery notification" with the sender supplied message delivery notifier object passed the return value from the handler doesn't feel too weird to include at the low level, and shouldn't cost anything for a void return without notification. Interestingly, the option to generate a a notification that a message with a handler returning void has been processed doesn't seem like a strange feature when looked at this way (a void future is a bit odd though).
Followed everything up to the point where you start discussing "return values". On one hand you do discuss this as simply another message. OTOH you do persist with some method-based concepts. Maybe this is not significant.
Return values can be seen as a syntactic nicety. In implementation then it is just another message, but if a sender knows that the logical outcome of the processing of the message he is sending will be another message received from the other object, then you can remove two switches by binding both the addresses. This would particularly be of benefit if a message had dynamic dispatching, where a different handler was invoked depending on the current state of the receiver. Aside: the void future was a consequence of wrapping active behaviour around 'normal' object interactions. Say you had the following interaction: struct Engine { enum State { Idle, Running }; State state; Engine() : state(Idle) {} void start(void) { state = Running; } State get_state(void) { return state; } }; struct Controller { Engine& engine; Controller(Engine& e) : engine(e) {} void begin(void) { engine.begin() }; } int main(int, char**) { Engine engine; Controller controller(engine); controller.begin(); assert(e.get_state() == Engine::Running); } This would be fine if all objects were normal objects with synchronous behaviour, however, if the Engine and Controller were wrapped to become active, then there would be no guarantee that Controller::begin() would be processed before Engine::get_state(), unless the caller of Controller::begin() was forced to wait for the processing of that message to complete before continuing. I don't think a void future has any relevance for objects which are designed to be active. Matt