| /* |
| * Copyright (c) 2010-2012, 2014 Eike Stepper (Berlin, Germany) and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Caspar De Groot - initial API and implementation |
| */ |
| package org.eclipse.emf.cdo.internal.net4j; |
| |
| import org.eclipse.net4j.connector.ConnectorException; |
| import org.eclipse.net4j.connector.IConnector; |
| import org.eclipse.net4j.util.lifecycle.LifecycleException; |
| |
| /** |
| * @author Caspar De Groot |
| */ |
| public class ReconnectingCDOSessionImpl extends RecoveringCDOSessionImpl |
| { |
| private long reconnectInterval = 0; |
| |
| private int maxReconnectAttempts = Integer.MAX_VALUE; |
| |
| public ReconnectingCDOSessionImpl() |
| { |
| } |
| |
| public long getReconnectInterval() |
| { |
| return reconnectInterval; |
| } |
| |
| public void setReconnectInterval(long reconnectInterval) |
| { |
| this.reconnectInterval = reconnectInterval; |
| } |
| |
| public int getMaxReconnectAttempts() |
| { |
| return maxReconnectAttempts; |
| } |
| |
| public void setMaxReconnectAttempts(int maxReconnectAttempts) |
| { |
| this.maxReconnectAttempts = maxReconnectAttempts; |
| } |
| |
| @Override |
| public void setConnector(IConnector connector) |
| { |
| // Do nothing (ignore an externally configured connector) |
| // Note: we cannot throw UnsupportedOperationException because the |
| // SessionConfig object will call this. |
| } |
| |
| @Override |
| public void setRepositoryConnectorDescription(String description) |
| { |
| if (getRepositoryConnectorDescription() != null) |
| { |
| throw new IllegalStateException("Don't call setRepositoryConnectorDescription more than once"); |
| } |
| |
| super.setRepositoryConnectorDescription(description); |
| } |
| |
| @Override |
| protected void updateConnectorAndRepositoryName() |
| { |
| removeTCPConnector(); |
| |
| IConnector newConnector = null; |
| int failedAttempts = 0; |
| long startOfLastAttempt = 0; |
| |
| while (newConnector == null && failedAttempts < maxReconnectAttempts) |
| { |
| try |
| { |
| if (startOfLastAttempt > 0) |
| { |
| delayAsNeeded(startOfLastAttempt); |
| } |
| |
| startOfLastAttempt = System.currentTimeMillis(); |
| newConnector = createTCPConnector(getUseHeartBeat()); |
| } |
| catch (ConnectorException ex) |
| { |
| failedAttempts++; |
| } |
| catch (LifecycleException ex) |
| { |
| failedAttempts++; |
| } |
| } |
| |
| if (newConnector == null) |
| { |
| throw new RuntimeException("Recovery failed"); // TODO (CD) Create custom exception type? |
| } |
| |
| super.setConnector(newConnector); |
| } |
| |
| private void delayAsNeeded(long startOfLastAttempt) |
| { |
| long timeToWait = requiredDelay(startOfLastAttempt); |
| while (timeToWait > 0) |
| { |
| try |
| { |
| Thread.sleep(timeToWait); |
| timeToWait = 0; |
| } |
| catch (InterruptedException ex) |
| { |
| timeToWait = requiredDelay(startOfLastAttempt); |
| } |
| } |
| } |
| |
| private long requiredDelay(long startOfLastAttempt) |
| { |
| long now = System.currentTimeMillis(); |
| long timeSinceLastAttempt = now - startOfLastAttempt; |
| long timeToWait = reconnectInterval - timeSinceLastAttempt; |
| return timeToWait; |
| } |
| } |