|
Boost : |
From: scott (scottw_at_[hidden])
Date: 2004-02-23 21:43:33
> -----Original Message-----
> From: boost-bounces_at_[hidden]
> [mailto:boost-bounces_at_[hidden]]On Behalf Of Matthew Vogt
> Sent: Tuesday, February 24, 2004 12:06 PM
> To: boost_at_[hidden]
> Subject: [boost] Re: [Threads] Simple active object wrapper, take 2
>
>
> scott <scottw <at> qbik.com> writes:
>
> Well, ok. Futures (in my code, and in the pattern) do allow
> a caller to
> access a result asynchronously, if you define asynchronously
> to mean that
> the caller is free to pursue other interests before acquiring
> the result.
>
> What is lacking is the ability to multiplex over events
> relating to the
> delivery of future values. You can't use select, poll or
> WFMO to determine
> whether any of an outstanding set of futures have been
> delivered. I think
> that this probably makes active objects an inappropriate
> choice for designs
> that are inherently reactive.
Yes, exactly. Is there no potential to leverage the mechanism
you already have, i.e. "task"?
It seems almost tragic that you have such a slick method of
delivering "Method Requests" and that it cant be used to deliver
"Method Results" asynchronously.
In another implementation this just involved storing some kind
of "return address" and adding that to the queued object (task).
On actual execution the thread (belonging to the active object)
need only turn around and write the results back into the callers
queue.
This all assumes that we are discussing symmetric activation. And
even want to go there :-)
> You could apply the active object pattern to this design, but
> the simplest
> way to do so would be to constrain the slave threads to have
> void-returning
<snip>
> (I think this is a variant on the 'half-sync, half-asynch' pattern?)
>
> Ideally, though, the server is a reactive design and not
> terribly suited to
> the active object pattern.
>
<snip>
>
> Well, yes, you could (and it could certainly be generic, I'm
> sure). But it
> doesn't seem to be in the spirit of the design. Active
> object is a trade-off
> between simplicity at the client, and suboptimal performance
> at the server.
>
<snip>
>
> This is certainly achievable, but is it using the active
> object design? You
> can implement an exactly equivalent design using the platform
> AIO primitives,
> but this would yield code which was much harder to follow and
> implement
> than active objects communicating through function calls. If
> you want
> optimum throughput throughout the interracting components, I
> don't think
> active object is the pattern you're looking for.
>
<snip>
I included the last few fragments of your message to give myself
an opportunity to review them as a group.
Yes, I understood most of your points. Some of the confusion or
gray areas in our exchange have been due to the mis-application
(mine) of the ActiveObject pattern.
The ActiveObject pattern was introduced early on and became a
convenient vocabulary and point of reference. In truth it was
never my target (I hadnt seen it previous to our discussion).
It is totally impressive work but does duck a major nasty.
So, to hopefully clarify; I still feel there is a software abstraction
that we (as developers) intuitively want. It is not completely
delivered by the ActiveObject pattern (though I thank JG again for
the reference).
As mentioned in my previous message the pattern has no mechanism
for asynchronous return of results. This is a source of wonderment
(tending towards frustration) as (IMHO) this is the Missing Link.
The frustration stems from the fact that all the machinery is
inherently available having previously implemented the delivery
of "Method Requests". Just "turn it around" and let the completing
method deliver the results to the original caller :-)
>
> The asynchronous delivery mechanism is the conversion of the
> 'future' template
> object to it's parameterised type. For example, the following blocks:
>
> future<int> f = someActiveObject.someMethod(); // Non-blocking
> int i = f; // Blocks
> until result delivered
>
> Of course, the caller may not need the result yet, and can
> postpone the wait
> indefinitely:
As I see it, futures is the closest that the asymmetric
activation can get to "async-res". But it isnt close enough.
When I refer to asyn-res I am typically referring to the
delivery of results from one active object to another, where
the receiving object is not required to enter into a
(potentially) blocking call (e.g. evaluation of a future).
I have tried to label this circumstance as "symmetric activation".
This can only occur between two active objects <cringe>.
Perhaps we could leave behind the "active object" term and
go for "reactive object"?
Perhaps you now own the "active object" name and the abstraction
that I continue to rave about, lays claim to "reactive object"?
> > It might be interesting to note that my ActiveWorld
> implementation is
> > _completely_
> > SA. The very pleasant surprise for me has been the
> successful manner in
> > which
> > it has been deployed in existing codebases. It may appear
> foreign but our
> > best
> > coding is naturally trying to emulate the SA ActiveObject.
> >
>
> What interface are you using to allow active objects to access results
> generated by other active objects?
>
The short answer is; the same interface used to deliver Method Requests. The
long answer would definitely be long. I can post some code fragments if we
are still swimming after the same stick?
> methods
> > of that same struct and those methods are only every called by
> > "boost::thread thread"
> > in "class active". Voila! We dont need any mutexes around that data!
> >
>
> Yes, but that only applies to a single-threaded active object.
<sigh, lowers shoulders> ;-)
In my ActiveWorld, no active object has more than a single thread. They
are either no thread (i.e. servants) or single-thread (a scheduler
deriving from the servant interface).
Where an active object deploys "slave threads", these are also zero
or one thread, i.e. they are also active objects.
This may sound unnecessarily convoluted but this small object hierarchy
provides the basis for building arbitrary hierarchies of threads. If
that is what you want :-) The big plus being that there is only the
one mechansim being used for inter-thread communication.
Within this object hierarchy and threading model (that I am making such
a meal of) any data declared with private scope in "struct object"
is thread-safe. Yes, because there is only ever the one thread :-)
Its been fun up to this point but perhaps your "code with legs" is
viable as "active object" and that is a valid first phase? I could
wheel my barrow off to the side for a while :-)
Cheers,
Scott
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk