Hey,
One of the ideas with side-effects is that it should be possible to
invoke them asynchronously. For this reason, in an design-up-front kind
of thing, we added the @Asynchronous annotation to be added to
side-effects that should be invoked asynchronously.
Now I'm not too sure that's a good idea. The reason is that there are so
many ways to invoke side-effects asynchronously (separate thread, put in
JMS queue, send to JavaSpace, etc.), and they all have different
semantics, that I don't think it's going to be so easy as to just mark a
side-effect as @Asynchronous and that's it.
I'm not sure how to do it instead, but one way is to push the
responsibility to the implementor. Basically in the side-effect
implementation it can use whatever method it wants, and
delegate to it. If the implementation being delegated to takes a
reasonably generic interface as input (such as InvocationHandler) this
will not tie the actual application code to it.
I have as a test implemented a generic side-effect that delegates to a
Java 5 Executor (implemented by a threadpool), which in turn is
implemented as a ServiceComposite so that it is activated/passivated
when the application starts/stops. Here's the application code that uses it:
@SideEffects(ExecutorSideEffect.class)
@Mixins(TestMixin.class)
public interface TestComposite
extends Composite
{
@ExecuteSideEffect( LogCall.class)
String doStuff();
}
---
Here I declare the ExecutorSideEffect to be used, and then the
annotation declares what it should instantiate and delegate to when
invoked. The ExecutorSideEffect has @AppliesTo(ExecuteSideEffect.class)
of course.
The LogCall could be implemented like this:
public static class LogCall
implements InvocationHandler
{
public Object invoke( Object o, Method method, Object[] objects )
throws Throwable
{
System.out.println("Called "+method.getName());
return null;
}
}
---
The ExecutorSideEffect hence simply puts a Runnable onto the Executor
service which when executed instantiates and injects the LogCall, and
then invokes it. Voila, asynchronous side-effects.
With this pattern any extra configuration for the asynchronous part can
be put into the annotation. For example, if the job should be posted to
a JMS queue it could specify the name of it, or specify the name of a
configuration where it is configured. If the job should be executed in a
delayed manner it could specify the delay, etc. There's a lot of
flexibility here since the annotation is essentially application code.
Whaddyathink? Does it make sense?
/Rickard
_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev