title: How to quickly check RMI registry?
body: <p>I'm trying to implement the Raft Consensus Algorithm for a Distributed System project.</p>
  
  <p>I need some very quickly way to know if a server A is reachable from a server B AND A's Distributed System is up. In other words, it could happen that the A is reachable by B but the A's cloud system isn't up yet. So I think that <code>InetAddress.getByName(ip).isReachable(timeout);</code> isn't enough.</p>
  
  <p>Since each server's stub is renamed as the server's name, I thought to get the server's registry and then check if there exists a stub with the same name of the server: if it's not the case, then skip to the next server, otherwise execute the <code>lookup</code> (which can take a looong time). This is part of the code:</p>
  
  <pre><code>try {
      System.out.println("Getting "+clusterElement.getId()+"'s registry");
      Registry registry = LocateRegistry.getRegistry(clusterElement.getAddress());
      System.out.println("Checking contains:");
      if(!Arrays.asList(registry.list()).contains(clusterElement.getId())) {
          System.out.println("Server "+clusterElement.getId()+" not bound (maybe down?)!");
          continue;
      }
      System.out.println("Looking up "+clusterElement.getId()+"'s stub");
      ServerInterface stub = (ServerInterface) registry.lookup(clusterElement.getId());
      System.out.println("Asking vote to "+clusterElement.getId());
      //here methods are called on stub (exploiting costum SocketFactory)
  } catch (NoSuchObjectException | java.rmi.ConnectException | java.rmi.ConnectIOException e){
      System.err.println("Candidate "+serverRMI.id+" cannot request vote to "+clusterElement.getId()+" because not reachable");
  } catch (UnmarshalException e) {
      System.err.println("Candidate " + serverRMI.id + " timeout requesting vote to " + clusterElement.getId());
  } catch (RemoteException e) {
      e.printStackTrace();
  } catch (NotBoundException e) {
     System.out.println("Candidate "+serverRMI.id+" NotBound "+clusterElement.getId());
  }
  </code></pre>
  
  <p>Now the problem is that the server gets stuck on the <code>contains()</code> line, since the message <code>Checking contains</code> is printed while <code>Looking up...</code> isn't.</p>
  
  <p>Why this happens? There is any way to speed up the process? This algorithm is <strong>FULL</strong> of timeouts, so any suggestion would be really appreciated!</p>
  
  <p><strong>UPDATE:</strong>
  After trying every possible VM property about RMI's timeouts, like:
  <code>-Dsun.rmi.transport.tcp.responseTimeout=1 -Dsun.rmi.transport.proxy.connectTimeout=1 -Dsun.rmi.transport.tcp.handshakeTimeout=1</code>
  I didn't see any difference at all, even if the an exception should have been thrown at every RMI operation (since each timeout is set to 1 ms!).</p>
  
  <p>The only solution that I found out for this problem is to use this <code>RMISocketFactory</code> reimplementation:</p>
  
  <pre><code>final int timeoutMillis = 100;            
  RMISocketFactory.setSocketFactory( new RMISocketFactory()
              {
                  public Socket createSocket( String host, int port )
                          throws IOException
                  {
                      Socket socket = new Socket();
                      socket.setSoTimeout(timeoutMillis);
                      socket.connect(new InetSocketAddress(host, port), timeoutMillis);
                      return socket;
                  }
  
                  public ServerSocket createServerSocket( int port )
                          throws IOException
                  {
                      return new ServerSocket( port );
                  }
              } );
  </code></pre>