Since I badly needed to be able to detected connect failures without
having to wait for a ConnectFuture I added support for it. See the
attached patch. Basically what I've done is to add an extra callback to
IoHandler:
void connectFailed( Throwable cause, Object mark ) throws Exception;
Then there is an extra connect-method in IoConnector:
ConnectFuture connect( SocketAddress address, SocketAddress localAddress,
IoHandler handler, Object mark ) throws
IOException;
When connect fails for any of the IoConnector implementations they will
notify the IoHandler specified in the call to connect() and pass along
the mark Object. That's it.
NOTE: I had to move the call to sessionCreated in
DatagramConnectorDelegate.regsiterNew() down a bit to make it less
likely that sessionCreated() is called even if connect fails.
Is this something that could be considered for inclusion in Mina?
/Niklas
Niklas Therning wrote:
>Forgot the [mina] prefix. Sorry.
>
>Hi,
>
>Is there any way I can detect if a connect operation fails without
>having to join or poll the ConnectFuture returned by connect()?
>
>/Niklas
>
>
>
>
Index: src/java/org/apache/mina/common/IoHandler.java
===================================================================
--- src/java/org/apache/mina/common/IoHandler.java (revision 332465)
+++ src/java/org/apache/mina/common/IoHandler.java (working copy)
@@ -68,6 +68,17 @@
void exceptionCaught( IoSession session, Throwable cause ) throws Exception;
/**
+ * Invoked when a connect operation fails for some reason.
+ *
+ * @param cause the Exception thrown by the connect operation if any.
+ * @param mark the same Object passed to the connect method.
+ * @see IoConnector#connect(SocketAddress, IoHandler)
+ * @see IoConnector#connect(SocketAddress, SocketAddress, IoHandler)
+ * @see IoConnector#connect(SocketAddress, SocketAddress, IoHandler, Object)
+ */
+ void connectFailed( Throwable cause, Object mark ) throws Exception;
+
+ /**
* Invoked when protocol message is received. Implement your protocol flow
* here.
*/
Index: src/java/org/apache/mina/common/IoHandlerAdapter.java
===================================================================
--- src/java/org/apache/mina/common/IoHandlerAdapter.java (revision 332465)
+++ src/java/org/apache/mina/common/IoHandlerAdapter.java (working copy)
@@ -51,6 +51,10 @@
{
}
+ public void connectFailed( Throwable cause, Object mark ) throws Exception
+ {
+ }
+
public void messageReceived( IoSession session, Object message ) throws Exception
{
}
Index: src/java/org/apache/mina/common/IoConnector.java
===================================================================
--- src/java/org/apache/mina/common/IoConnector.java (revision 332465)
+++ src/java/org/apache/mina/common/IoConnector.java (working copy)
@@ -64,6 +64,17 @@
IoHandler handler ) throws IOException;
/**
+ * Connects to the specified <code>address</code>. If communication starts
+ * successfully, events are fired to the specified
+ * <code>handler</code>.
+ *
+ * @param localAddress the local address the channel is bound to
+ * @throws IOException if failed to connect
+ */
+ ConnectFuture connect( SocketAddress address, SocketAddress localAddress,
+ IoHandler handler, Object mark ) throws IOException;
+
+ /**
* Returns the connect timeout in seconds.
*/
int getConnectTimeout();
Index: src/java/org/apache/mina/common/support/DelegatedIoConnector.java
===================================================================
--- src/java/org/apache/mina/common/support/DelegatedIoConnector.java (revision 332465)
+++ src/java/org/apache/mina/common/support/DelegatedIoConnector.java (working copy)
@@ -56,6 +56,12 @@
return delegate.connect( address, localAddress, handler );
}
+ public ConnectFuture connect( SocketAddress address, SocketAddress localAddress,
+ IoHandler handler, Object mark ) throws IOException
+ {
+ return delegate.connect( address, localAddress, handler, mark );
+ }
+
public IoFilterChain getFilterChain()
{
return delegate.getFilterChain();
Index: src/java/org/apache/mina/transport/vmpipe/VmPipeConnector.java
===================================================================
--- src/java/org/apache/mina/transport/vmpipe/VmPipeConnector.java (revision 332465)
+++ src/java/org/apache/mina/transport/vmpipe/VmPipeConnector.java (working copy)
@@ -51,11 +51,16 @@
public ConnectFuture connect( SocketAddress address, IoHandler handler ) throws IOException
{
- return connect( address, null, handler );
+ return connect( address, null, handler, null );
}
public ConnectFuture connect( SocketAddress address, SocketAddress localAddress, IoHandler handler ) throws IOException
{
+ return connect( address, localAddress, handler, null );
+ }
+
+ public ConnectFuture connect( SocketAddress address, SocketAddress localAddress, IoHandler handler, Object mark ) throws IOException
+ {
if( address == null )
throw new NullPointerException( "address" );
if( handler == null )
Index: src/java/org/apache/mina/transport/socket/nio/support/DatagramConnectorDelegate.java
===================================================================
--- src/java/org/apache/mina/transport/socket/nio/support/DatagramConnectorDelegate.java (revision 332465)
+++ src/java/org/apache/mina/transport/socket/nio/support/DatagramConnectorDelegate.java (working copy)
@@ -77,6 +77,12 @@
public ConnectFuture connect( SocketAddress address, SocketAddress localAddress,
IoHandler handler ) throws IOException
{
+ return connect( address, localAddress, handler, null );
+ }
+
+ public ConnectFuture connect( SocketAddress address, SocketAddress localAddress,
+ IoHandler handler, Object mark ) throws IOException
+ {
if( address == null )
throw new NullPointerException( "address" );
if( handler == null )
@@ -113,7 +119,7 @@
}
}
- RegistrationRequest request = new RegistrationRequest( ch, handler );
+ RegistrationRequest request = new RegistrationRequest( ch, handler, mark );
synchronized( this )
{
synchronized( registerQueue )
@@ -177,7 +183,7 @@
flushingSessions.push( session );
}
}
-
+
private class Worker extends Thread
{
public Worker()
@@ -416,18 +422,20 @@
boolean success = false;
try
{
- session.getManagerFilterChain().sessionCreated( session );
SelectionKey key = req.channel.register( selector,
SelectionKey.OP_READ, session );
session.setSelectionKey( key );
+ session.getManagerFilterChain().sessionCreated( session );
+
req.setSession( session );
success = true;
}
catch( Throwable t )
{
+ callConnectFailed( t, req );
req.setException( t );
}
finally
@@ -447,6 +455,18 @@
}
}
+ private void callConnectFailed( Throwable cause, RegistrationRequest req )
+ {
+ try
+ {
+ req.handler.connectFailed( cause, req.mark );
+ }
+ catch ( Exception e )
+ {
+ exceptionMonitor.exceptionCaught( this, e );
+ }
+ }
+
private void cancelKeys()
{
if( cancelQueue.isEmpty() )
@@ -491,12 +511,15 @@
private final DatagramChannel channel;
private final IoHandler handler;
-
+
+ private Object mark;
+
private RegistrationRequest( DatagramChannel channel,
- IoHandler handler )
+ IoHandler handler, Object mark )
{
this.channel = channel;
this.handler = handler;
+ this.mark = mark;
}
}
}
Index: src/java/org/apache/mina/transport/socket/nio/support/SocketConnectorDelegate.java
===================================================================
--- src/java/org/apache/mina/transport/socket/nio/support/SocketConnectorDelegate.java (revision 332465)
+++ src/java/org/apache/mina/transport/socket/nio/support/SocketConnectorDelegate.java (working copy)
@@ -34,9 +34,6 @@
import org.apache.mina.common.IoHandler;
import org.apache.mina.common.support.BaseIoConnector;
import org.apache.mina.common.support.IoSessionManagerFilterChain;
-import org.apache.mina.transport.socket.nio.support.SocketIoProcessor;
-import org.apache.mina.transport.socket.nio.support.SocketSessionImpl;
-import org.apache.mina.transport.socket.nio.support.SocketSessionManagerFilterChain;
import org.apache.mina.util.ExceptionUtil;
import org.apache.mina.util.Queue;
@@ -69,12 +66,18 @@
public ConnectFuture connect( SocketAddress address, IoHandler handler ) throws IOException
{
- return connect( address, null, handler);
+ return connect( address, null, handler, null );
}
public ConnectFuture connect( SocketAddress address, SocketAddress localAddress,
IoHandler handler ) throws IOException
{
+ return connect( address, localAddress, handler, null );
+ }
+
+ public ConnectFuture connect( SocketAddress address, SocketAddress localAddress,
+ IoHandler handler, Object mark ) throws IOException
+ {
if( address == null )
throw new NullPointerException( "address" );
if( handler == null )
@@ -119,7 +122,7 @@
}
}
- ConnectionRequest request = new ConnectionRequest( ch, getConnectTimeout(), handler );
+ ConnectionRequest request = new ConnectionRequest( ch, getConnectTimeout(), handler, mark );
synchronized( this )
{
synchronized( connectQueue )
@@ -166,6 +169,7 @@
}
catch( IOException e )
{
+ callConnectFailed( e, req );
req.setException( e );
}
}
@@ -195,6 +199,7 @@
}
catch( Throwable e )
{
+ callConnectFailed( e, entry );
entry.setException( e );
}
finally
@@ -233,12 +238,14 @@
if( currentTime >= entry.deadline )
{
- entry.setException( new ConnectException() );
+ ConnectException e = new ConnectException();
+ callConnectFailed( e, entry );
+ entry.setException( e );
key.cancel();
}
}
}
-
+
private SocketSessionImpl newSession( SocketChannel ch, IoHandler handler ) throws IOException
{
SocketSessionImpl session = new SocketSessionImpl( filters, ch, handler );
@@ -254,6 +261,18 @@
return session;
}
+ private void callConnectFailed( Throwable cause, ConnectionRequest req )
+ {
+ try
+ {
+ req.handler.connectFailed( cause, req.mark );
+ }
+ catch ( Exception e )
+ {
+ exceptionMonitor.exceptionCaught( this, e );
+ }
+ }
+
private class Worker extends Thread
{
public Worker()
@@ -326,12 +345,15 @@
private final long deadline;
private final IoHandler handler;
+
+ private final Object mark;
- private ConnectionRequest( SocketChannel channel, int timeout, IoHandler handler )
+ private ConnectionRequest( SocketChannel channel, int timeout, IoHandler handler, Object mark )
{
this.channel = channel;
this.deadline = System.currentTimeMillis() + timeout * 1000L;
this.handler = handler;
+ this.mark = mark;
}
}