|
What I thought was something like this:
1) Add a "Callback" interface to IoFuture, and a "setCallback" method. This allows the result of any IoFuture to be obtained "callback style" (So I can do my write callbacks... yeah!!). 2) Add a "ConnectListener" interface to ConnectFuture. This is more specific, and has the methods you mention above. Add a "setConnectListener" method to ConnectFuture. 3) Internally, a private adapter class adapts ConnectListeners to Callbacks. So when you do a setConnectListener, it creates a CallbackAdapter and sets it as the futures callback. This means that ConnectFuture can still have a more specific callback interface (succeeded / failed), but we can still get callbacks for any other type of future. I'm going to attach the two associated files now.... WDYT? Added ConnectListener and Callback adapter to ConnectFuture
Thanks for the patch!
I modified your path a little bit: public interface Callback { /** * Invoked when the operation associated with the {@link IoFuture} * succeeded. * * @param source The source {@link IoFuture} which called this * callback. * @param result The result value of the operation. Its type * depends on what I/O operation you requested. */ public void operationSucceeded( IoFuture source, Object result ); /** * Invoked when the operation associated with the {@link IoFuture} * failed. * * @param source The source {@link IoFuture} which called this * callback * @param cause The cause of failure */ public void operationFailed( IoFuture source, Throwable cause ); } Providing two methods by default, I think we don't need to add ConnectListener or other possible listeners IMHO though this will cause an inevitable downcasting. WDYT? It seems like Apache web server is not available at the moment. I'll check in the fix when I get a chance.
> Providing two methods by default, I think we don't need to add ConnectListener
> or other possible listeners IMHO though this will cause an inevitable downcasting. WDYT? Yeah - makes sense. I started out with doing it the "operationSucceeded" / "operationFailed" way in IoFuture. Then I had a look at the existing implementations (write, close) and there didn't seem to be a common "failure" possibility. So the down side of having a common failure case in the callback seemed to be that each (client) implementation would have to implement operationFailed - even though it wouldn't ever be called. Having the base callback just having "operationCompleted" meant that the futures themselves could add any extra meaning to this if desired, but wouldn't require client code to do so. Any downcasting is limited to the implementation details of the future itself (and not client code). I guess its a trade off :o) If we dont mind all client Callback implementations having to implement operationFailed when it wont ever be called - then this is definately a cleaner approach. Dave I thought over your opinion and found the simpler way:
http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/common/IoFuture.java?rev=343990&r1=343989&r2=343990&view=diff If we're going to downcast, why not downcasting IoFuture itself like this? ConnectFuture future = ...; future.setCallback( new Iofuture.Callback() { public void operationComplete( IoFuture future ) { ConnectFuture cf = ( ConnectFuture ) future; try { IoSession session = cf.getSession(); } ... } }); Yeah - that looks great. It keeps the flexibility, whilst removing the extra complexity from the actual IoFuture implementations! Thanks!
Now callbacks are fully supported thanks to Dave Irving's support. :)
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
I've got a feeling that this might be useful for IoFutures in general.
For example, I currently need to know when I've fully written a clients "last response" so that I can initiate connection closure.
For me, a very clean way would be to schedule a listener with a WriteFuture.
I'll have a tinker and see if I can get something built in to IoFuture....