Hi Ignacio,
Let's try IRC, perhaps Monday's chat? Other comments inline...
On Jun 30, 2006, at 1:30 PM, Ignacio Silva-Lepe wrote:
Apologies Jeremy, didn't mean to exclude people, just trying
to expedite the discussion.
The first basic issue I see is how to incorporate callbacks as
defined in the C&I spec in particular, and bi-directional
interfaces in general, into the Tuscany architecture.
Depending on how closely a RuntimeWire is supposed to
correspond to an SCA wire, it seems like one way to
incorporate a callback is to extend InboundWire to include an
OutboundInvocationChain, and OutboundWire to include an
InboundInvocationChain. That is, a wire would include a
'reverse' pair of invocation chain ends to account for a
callback.With that in place, it seems feasible to re-use
WireInvocationHandler and TargetInvoker in a similar fashion
to actually perform the callback invocation. Are there any
subtle (or not so subtle) gotchas in this that I am overlooking?
I was thinking there would be a couple of things: a system
transport service and a "conversational" scope container. The
system transport service would listen for callbacks. That
service would dispatch and invoke a component, which in turn
would ask its scope container for the component implementation
instance to dispatch to.
Not sure if I follow. Is the system transport service intended
as an alternative
for a reverse invocation chain pair?
Yes. The system service would be a transport listener which would
pick up the callback invocation off of a wire. The callback
invocation would be sent from the proxy injected into the target
as described below. Do you think it would help if we outlined
several of scenarios, e.g. a stateless callback done in the same
composite, a stateless callback done across remote boundaries, a
stateful callback done in the same composite, and a stateful
callback done across remote boundaries? I was thinking we could
sketch out what happens and then map it down to the core.
If I understand correctly, would a system service transport use a
low level
communication mechanism, like a socket for instance? This does not
seem like
an appropriate approach for a local scenario,
Right, for the local scenario, I was thinking the callback instance
would be put on the thread local context and the proxy would access
it from there as opposed to going out over a socket and back in
through a listener. Basically, it would be an optimization of the
remote case. I think we can further optimize things depending on
scopes, e.g. if the callback scope is "module", we could possibly
avoid threadlocal storage and have the proxy hold on to an instance
directly.
but I am really guessing about
how such a listener would pick up a callback invocation if it is
not via the
architected RuntimeWire/InvocationChain mechanism. On the other hand,
you do say the listener would pick up the callback invocation off
of a wire,
which I'm not sure I follow either.
In the remote case, the target proxy would perform the invocation
over a particular transport, which the listener would be listening
on. The callback invocation would then be handled like any component
invocation.
Admittedly, using a 'reverse' pair of invocation chains does not
seem like a
very orthodox approach, but given that the SCA architecture does
not define
separate reference and service elements for a callback (i.e., these
seem to be
bundled into the forward reference and service only in reverse), it
looks like it is
up to the Tuscany architecture to supply a sensible design. As an
alternative,
a separate RuntimeWire instance could be introduced for a callback,
with
corresponding outbound and inbound ends, but this would not
correspond that
closely to its SCA counterpart.
I think part of the problem may be that wires in SCA are
bidirectional while in Java a "reference pointer" is unidirectional.
We could look to try and model this with the approach you are
proposing since it may be closer to the bidirectional nature of
wires. Maybe on IRC we can come up with the scenarios and then
outline the two approaches (we can post the transcript)? If we have
difficulty on IRC due to the complexity of the topic, we may have to
do a call and we could post to the list a summary of what was discussed.
My question about gotchas had more to do with trying to use a
WireInvocationHandler
(e.g., JDKOutboundInvocationHandler) as the object called by the
callback proxy
injected into the target.
I'd like to talk about this more since I'm not sure I'm getting
everything (email is difficult).
At first glance, this seems feasible, even if we are performing
an outbound invocation on an InboundWire and the corresponding
inbound invocation
of the client happens from an OutboundWire. Is this reversal the
reason why a transport
listener is a better approach in your mind Jim? One concern I have
(if I understand
the transport listener idea) is that it seems like a departure from
the current architecture.
I'm not sure it is a departure as opposed to an "addition" that may
be simpler to manage from a code perspective. It's kind of just how
I thought initially about doing things but I think we should explore
a bunch of approaches. My preference is if we can realistically model
things to the spec then we should do it though.
That is, there is no such listener used in a forward invocation.
I need to run out for a bit now, but let me think about it more and I
will post a follow-up. Then, perhaps we can chat on IRC on Monday or
set aside another time to do so?
Jim
The conversational scope container could have a pluggable
persistent store API (we could have a simple implementation
which serialized to disk and eventually used a journaling
mechanism such as HOWL http:// howl.objectweb.org/).
Two other basic pieces are: (1) callback injection, and (2)
implementation of ServiceReference. Callback injection may be
simple enough and similar to reference injection for
stateless callbacks, but it'll get more interesting for
stateful callbacks (or stateful scopes), as it is not clear
that a callback field or method will remain valid for the
duration of the component instance, and may need to be re-
injected.
Couldn't we use a proxy for this to avoid reinjection? In terms
of flow, it could possibly work as follows:
1. Client invokes, invocation is passed through a wire
2. Target is invoked. When the target is created (it could be
at this point or before), a callback proxy is injected. During
the invocation, a threadlocal context is set up which allows
the proxy to dispatch back.
3. Target calls the callback and an invocation is dispatched back
4. The listener on the client end receives the calback and
dispatches to the callback using a normal component invocation.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]