Issue Details (XML | Word | Printable)

Key: DIRMINA-120
Type: Improvement Improvement
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Trustin Lee
Reporter: Trustin Lee
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
MINA

Callbacks for IoFutures

Created: 12/Nov/05 08:33 AM   Updated: 14/Nov/05 06:37 PM
Return to search
Component/s: None
Affects Version/s: None
Fix Version/s: 0.9.0

Time Tracking:
Not Specified

File Attachments:
  Size
Java Source File Licensed for inclusion in ASF works ConnectFuture.java 2005-11-12 07:35 PM dave irving 4 kB
Java Source File Licensed for inclusion in ASF works IoFuture.java 2005-11-12 07:34 PM dave irving 4 kB

Resolution Date: 14/Nov/05 06:37 PM


 Description  « Hide
IoFuture provides only blocking-way ('join' method) for user to find out the result of an I/O request. It would be great if users can specify a callback:

ConnectFuture future = connector.connect(...);
future.setCallback( new ConnectFuture.Callback() {
    public void connectionEstablished( IoSession session ) {
    }
    public void connectionFailed( Throwable cause ) {
    }
} );

There can be a race condition if the connection process ends before a user calls setCallback() method, but we can resolve this carefully so users don't notice any issue.

 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
dave irving added a comment - 12/Nov/05 07:00 PM
Hi

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....

dave irving added a comment - 12/Nov/05 07:32 PM
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?

dave irving added a comment - 12/Nov/05 07:34 PM
Added Callback to IoFuture

dave irving added a comment - 12/Nov/05 07:35 PM
Added ConnectListener and Callback adapter to ConnectFuture

Trustin Lee added a comment - 13/Nov/05 12:27 PM
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?

Trustin Lee added a comment - 13/Nov/05 12:28 PM
It seems like Apache web server is not available at the moment. I'll check in the fix when I get a chance.

dave irving added a comment - 13/Nov/05 09:04 PM
> 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

Trustin Lee added a comment - 14/Nov/05 07:33 AM
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();
        } ...
    }
});

dave irving added a comment - 14/Nov/05 06:05 PM
Yeah - that looks great. It keeps the flexibility, whilst removing the extra complexity from the actual IoFuture implementations! Thanks!

Trustin Lee added a comment - 14/Nov/05 06:37 PM
Now callbacks are fully supported thanks to Dave Irving's support. :)