package org.distributeme.core.failing; import org.distributeme.core.ClientSideCallContext; import org.distributeme.core.routing.AbstractRouter; import org.distributeme.core.routing.RegistrationNameProvider; import org.distributeme.core.routing.Router; /** * This is base class for failing strategy / router combination which is pretty much the same as Failover, but instead of staying on * the failover instance forever, it tries to switch back after some timeout. * * @author another * @version $Id: $Id */ public abstract class FailoverAndReturn extends AbstractRouter implements FailingStrategy, RegistrationNameProvider, Router{ /** * Target service id after first failover. */ private String failedOverServiceId = null; /** * Timestamp in ms of last failover event. */ private long failoverTimestamp = 0L; /** * Seconds in ms. */ protected static final long SECOND = 1000L; /** * Minutes in ms. */ protected static final long MINUTE = SECOND*60; /** * Returns the time unit in milliseconds between the router retries to get back to original server. * * @return a long. */ protected abstract long getFailbackTimeout(); /** {@inheritDoc} */ @Override public String getServiceIdForCall(ClientSideCallContext callContext) { resetFailOverAfterTimeFailbackPeriod(callContext); if (!callContext.isFirstCall() && failedOverServiceId==null){ failedOverServiceId = callContext.getServiceId(); failoverTimestamp = System.currentTimeMillis(); } String ret = failedOverServiceId == null ? callContext.getServiceId() : failedOverServiceId; return ret; } private void resetFailOverAfterTimeFailbackPeriod(ClientSideCallContext callContext) { if (failoverTimestamp!=0 && callContext.isFirstCall() && (System.currentTimeMillis()-failoverTimestamp>getFailbackTimeout())){ failoverTimestamp = 0; failedOverServiceId = null; } } /** * Suffix of the failover instance. */ public static final String SUFFIX = "-failover"; /** {@inheritDoc} */ @Override public String getRegistrationName(String serviceId) { return serviceId+SUFFIX; } /** {@inheritDoc} */ @Override public void customize(String parameter) { // not used. } /** {@inheritDoc} */ @Override public FailDecision callFailed(ClientSideCallContext context) { FailDecision ret = FailDecision.retryOnce(); ret.setTargetService(context.getServiceId()+getSuffix()); return ret; } /** * <p>getSuffix.</p> * * @return a {@link java.lang.String} object. */ protected String getSuffix(){ return SUFFIX; } }