IT-5103 - Try to avoid "BindException: Address already in use" on build boxes when repeatedly stopping and starting the repository, by enabling retries (default for up to 1 second) when creating RMI Server Ports

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@30063 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Nick Burch
2011-08-25 14:16:06 +00:00
parent a6e115fdd5
commit bf057b35b1
4 changed files with 68 additions and 3 deletions

View File

@@ -6,6 +6,7 @@
<bean id="hostConfigurableSocketFactory" class="org.alfresco.util.remote.server.socket.HostConfigurableSocketFactory"> <bean id="hostConfigurableSocketFactory" class="org.alfresco.util.remote.server.socket.HostConfigurableSocketFactory">
<property name="host" value="${alfresco.rmi.services.host}" /> <property name="host" value="${alfresco.rmi.services.host}" />
<property name="retries" value="${alfresco.rmi.services.retries}" />
</bean> </bean>
<bean id="baseServiceExporter" class="org.springframework.remoting.rmi.RmiServiceExporter" abstract="true"> <bean id="baseServiceExporter" class="org.springframework.remoting.rmi.RmiServiceExporter" abstract="true">

View File

@@ -73,6 +73,9 @@
<property name="servicePort"> <property name="servicePort">
<value>${authentication.rmi.service.port}</value> <value>${authentication.rmi.service.port}</value>
</property> </property>
<property name="clientSocketFactory">
<ref bean="hostConfigurableSocketFactory" />
</property>
</bean> </bean>
<!-- A Simple Filesystem like API for the repo implementation. <!-- A Simple Filesystem like API for the repo implementation.

View File

@@ -497,6 +497,10 @@ policy.content.update.ignoreEmpty=false
# #
alfresco.rmi.services.host=0.0.0.0 alfresco.rmi.services.host=0.0.0.0
# If the RMI address is in-use, how many retries should be done before aborting
# Default value of alfresco.rmi.services.retries is 0 which means 'Don't retry if the address is in-use'
alfresco.rmi.services.retries=4
# RMI service ports for the individual services. # RMI service ports for the individual services.
# These eight services are available remotely. # These eight services are available remotely.
# #

View File

@@ -20,6 +20,7 @@ package org.alfresco.util.remote.server.socket;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.net.BindException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
@@ -28,6 +29,8 @@ import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory; import java.rmi.server.RMIServerSocketFactory;
import org.alfresco.util.EqualsHelper; import org.alfresco.util.EqualsHelper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
/** /**
@@ -46,6 +49,17 @@ import org.springframework.beans.factory.InitializingBean;
public class HostConfigurableSocketFactory implements RMIServerSocketFactory, RMIClientSocketFactory, Serializable public class HostConfigurableSocketFactory implements RMIServerSocketFactory, RMIClientSocketFactory, Serializable
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static Log logger = LogFactory.getLog(HostConfigurableSocketFactory.class);
/**
* How many retries to attempt if the socket is in use.
* Default is zero (no retries)
*/
private int retries = 0;
/**
* How long to wait between retries, in miliseconds?
*/
private int retryInterval = 250;
private InetAddress host; private InetAddress host;
@@ -65,6 +79,23 @@ public class HostConfigurableSocketFactory implements RMIServerSocketFactory, RM
} }
} }
/**
* How many retries to attempt if the socket is in use.
* Default is zero (no retries)
*/
public void setRetries(int retries)
{
this.retries = retries;
}
/**
* How long to wait between retries, in miliseconds?
*/
public void setRetryInterval(int retryInterval)
{
this.retryInterval = retryInterval;
}
public Socket createSocket(String host, int port) throws IOException public Socket createSocket(String host, int port) throws IOException
{ {
return new Socket(host, port); return new Socket(host, port);
@@ -72,7 +103,33 @@ public class HostConfigurableSocketFactory implements RMIServerSocketFactory, RM
public ServerSocket createServerSocket(int port) throws IOException public ServerSocket createServerSocket(int port) throws IOException
{ {
return new ServerSocket(port, 50, this.host); ServerSocket socket = null;
for(int i=0; socket == null && i<retries+1; i++)
{
try
{
socket = new ServerSocket(port, 50, this.host);
}
catch(BindException e)
{
if(i >= retries)
{
// We're out of retries, abort
throw e;
}
else
{
// Sleep and try again
logger.warn("Port in-use, retrying", e);
try
{
Thread.sleep(retryInterval);
}
catch(InterruptedException ie) {}
}
}
}
return socket;
} }
/* /*