Ignacio came up with a nice design and implementation (including a
presentation posted on the wiki) for callback support. I've applied
the patch as well as did a bit of refactoring that I will describe
below. There's still a lot of refactoring to be done and some things
that we will probably want to clean up a bit more. Also, callbacks
currently work from component-to-component invocations and not
through references (i.e. across remote boundaries).
The changes I made were:
1. Move the functionality of CallbackProcessor to ServiceProcessor
and HeuristicProcessor to avoid ordering problems. Specifically,
CallbackProcessor introspected the implementation class and added
callback information to the service located on the component type.
This assumes the service processor is invoked before the callback
processor, which in most cases it is, but may not be depending on
SCDL configuration ordering. To avoid this, and as callback
information is part of service processing, I moved it to the service
processor. The HeuristicProcessor may also need to analyze callback
information so I factored common methods to ProcessorUtils - not
ideal but given the complexities of introspecting implementation
artifacts it may be the best solution.
2. I changed the outbound wire on the source side to contain the
inbound callback wire *as well as* the outbound callback wire
associated with the target. So given:
@Callback(FooCallback.class)
interface Foo{
void call()
}
interface FooCallback{
void callback();
}
class Client implements FooCallback{
@Reference
protected Foo foo;
public void callback(){
System.out.println("received callback");
}
public void invoke(){
foo.call();
}
}
class FooImpl implements Foo{
@Callback
protected FooCallback callback;
public void call(){
callback.callback();
}
}
The builder is currently responsible for creating inbound and
outbound wires for a component (I intend to do a little refactoring
here but that's a different topic). For example, when building
Client, the builder will create the outbound wire for the "foo"
reference. When building FooImpl, it will create the inbound wire for
the "Foo" service. The Connector will bridge the two.
The builder is also responsible for creating inbound and outbound
callback wires. The one difference is that the outbound callback wire
is created by the builder when it evaluates the client component. For
example, when building Client, the outbound wire associated with the
"foo" reference will have both inbound and outbound callback wires on
it. These will be bridged by the connector. This allows all wires
within a composite to by "connected" and target wire resolution
avoided during invocation (remote invocations will need some
dynamicity). During an invocation, the AsyncTargetInvoker will set
the work context with the outbound callback wire. When a callback is
made by the target, the proxy invocation handler will pull the
outbound callback wire from the work context and send the invocation
down the correct chain. This will allow us to support the case where
two different client components may invoke a target and the callback
needs to resolve to the correct client.
I'm not sure this is the best approach to take so it would be worth
discussing further.
Things to do
---------------------
I'm going to take another pass at cleaning up the extension API and
some code refactorings.
We need to get callbacks working for References and this will involve
handling longer-term conversational state. I was thinking we will
need to have a durable persistent store tied to a conversational
scope container and we may be able to implement this as a write-
behind cache. The reference would flow the callback component id (a
FQN in the composite hierarchy) as well as an id associated with the
component implementation instance. The callback component id would be
used to resolve the correct callback wire, while the conversation id
would be used by the conversational scope container to resolve the
correct implementation instance, possibly deserializing it with its
state. As part of the serialization, we are going to need a way to
handle reference proxies that may be on the callback instance. For
example, Client may have other references pointing to other
components that need to be reactivated during the callback.
Anyone interested in working on this let Ignacio and I know.
Jim
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]