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, 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.
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.
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. 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.
That is, there is no such listener used in a forward invocation.
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]