All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gemstone.gemfire.internal.cache.wan.serial.SerialGatewaySenderImpl Maven / Gradle / Ivy

/*
 * Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License. You
 * may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License. See accompanying
 * LICENSE file.
 */
package com.gemstone.gemfire.internal.cache.wan.serial;

import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.asyncqueue.AsyncEventListener;
import com.gemstone.gemfire.cache.wan.GatewayTransportFilter;
import com.gemstone.gemfire.distributed.DistributedLockService;
import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
import com.gemstone.gemfire.distributed.internal.ResourceEvent;
import com.gemstone.gemfire.distributed.internal.DistributionAdvisor.Profile;
import com.gemstone.gemfire.internal.LogWriterImpl;
import com.gemstone.gemfire.internal.cache.EntryEventImpl;
import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
import com.gemstone.gemfire.internal.cache.RegionQueue;
import com.gemstone.gemfire.internal.cache.UpdateAttributesProcessor;
import com.gemstone.gemfire.internal.cache.wan.AbstractGatewaySender;
import com.gemstone.gemfire.internal.cache.wan.AbstractGatewaySenderEventProcessor;
import com.gemstone.gemfire.internal.cache.wan.GatewaySenderAttributes;
import com.gemstone.gemfire.internal.cache.wan.GatewaySenderConfigurationException;
import com.gemstone.gemfire.internal.cache.wan.GatewaySenderEventImpl;
import com.gemstone.gemfire.internal.cache.wan.GatewaySenderAdvisor.GatewaySenderProfile;
import com.gemstone.gemfire.internal.i18n.LocalizedStrings;

/**
 * @author Suranjan Kumar
 * @author Yogesh Mahajan
 * @since 7.0
 *
 */
public class SerialGatewaySenderImpl extends AbstractGatewaySender {

  final ThreadGroup loggerGroup = LogWriterImpl.createThreadGroup(
      "Remote Site Discovery Logger Group", this.logger);

  public SerialGatewaySenderImpl(Cache cache,
      GatewaySenderAttributes attrs) {
    super(cache, attrs);
  }
  
  final Object lockForConcurrentDispatcher = new Object();
  
  @Override
  public void start() {
    if (logger.fineEnabled()) {
      logger.fine("Starting gatewaySender : " + this);
    }
    this.lifeCycleLock.writeLock().lock();
    try {
      if (isRunning()) {
        if (logger.warningEnabled()) {
          logger.warning(
              LocalizedStrings.GatewaySender_SENDER_0_IS_ALREADY_RUNNING,
              this.getId());
        }
        return;
      }
      if (this.remoteDSId != DEFAULT_DISTRIBUTED_SYSTEM_ID) {
        String locators = ((GemFireCacheImpl)this.cache).getDistributedSystem()
            .getConfig().getLocators();
        if (locators.length() == 0) {
          throw new GatewaySenderConfigurationException(
              LocalizedStrings.AbstractGatewaySender_LOCATOR_SHOULD_BE_CONFIGURED_BEFORE_STARTING_GATEWAY_SENDER
                  .toLocalizedString());
        }
      }
      getSenderAdvisor().initDLockService();
      if (!isPrimary()) {
        if (getSenderAdvisor().volunteerForPrimary()) {
          getSenderAdvisor().makePrimary();
        } else {
          getSenderAdvisor().makeSecondary();
        }
      }
      if (getDispatcherThreads() > 1) {
        eventProcessor = new ConcurrentSerialGatewaySenderEventProcessor(
            SerialGatewaySenderImpl.this);
      } else {
        eventProcessor = new SerialGatewaySenderEventProcessor(
            SerialGatewaySenderImpl.this, getId());
      }
      eventProcessor.start();
      waitForRunningStatus();
      this.startTime = System.currentTimeMillis();
      final GemFireCacheImpl cache = (GemFireCacheImpl)getCache();
      cache.getPdxRegistry().gatewaySenderStarted(this);
      new UpdateAttributesProcessor(this).distribute(false);
      cache.gatewaySenderStarted(this);

      InternalDistributedSystem system = (InternalDistributedSystem) this.cache
          .getDistributedSystem();
      system.handleResourceEvent(ResourceEvent.GATEWAYSENDER_START, this);
      
      getLogger().info(LocalizedStrings.SerialGatewaySenderImpl_STARTED__0,
          this);
  
      enqueTempEvents();
    } finally {
      this.lifeCycleLock.writeLock().unlock();
    }
  }
  
  @Override
  public void stop() {
    if (this.logger.fineEnabled()) {
      this.logger.fine("Stopping Gateway Sender : " + this);
    }
    this.lifeCycleLock.writeLock().lock();
    try {
      // Stop the dispatcher
      AbstractGatewaySenderEventProcessor ev = this.eventProcessor;
      if (ev != null && !ev.isStopped()) {
        ev.stopProcessing();
      }
      this.eventProcessor = null;

      // Stop the proxy (after the dispatcher, so the socket is still
      // alive until after the dispatcher has stopped)
      stompProxyDead();

      // Close the listeners
      for (AsyncEventListener listener : this.listeners) {
        listener.close();
      }
      this.getLogger().info(LocalizedStrings.GatewayImpl_STOPPED__0, this);
      
      clearTempEventsAfterSenderStopped();
    } finally {
      this.lifeCycleLock.writeLock().unlock();
    }
    if (this.isPrimary()) {
      try {
        DistributedLockService
            .destroy(getSenderAdvisor().getDLockServiceName());
      } catch (IllegalArgumentException e) {
        // service not found... ignore
      }
    }
    if (getQueues() != null && !getQueues().isEmpty()) {
      for (RegionQueue q : getQueues()) {
        ((SerialGatewaySenderQueue)q).cleanUp();
      }
    }
    this.setIsPrimary(false);
    new UpdateAttributesProcessor(this).distribute(false);
    ((GemFireCacheImpl)getCache()).gatewaySenderStopped(this);

    Thread lockObtainingThread = getSenderAdvisor().getLockObtainingThread();
    if (lockObtainingThread != null && lockObtainingThread.isAlive()) {
      // wait a while for thread to terminate
      try {
        lockObtainingThread.join(3000);
      } catch (InterruptedException ex) {
        // we allowed our join to be canceled
        // reset interrupt bit so this thread knows it has been interrupted
        Thread.currentThread().interrupt();
      }
      if (lockObtainingThread.isAlive()) {
        getLogger()
            .info(
                LocalizedStrings.GatewayHubImpl_COULD_NOT_STOP_LOCK_OBTAINING_THREAD_DURING_GATEWAY_HUB_SHUTDOWN);
      }
    }
    
    InternalDistributedSystem system = (InternalDistributedSystem) this.cache
        .getDistributedSystem();
    system.handleResourceEvent(ResourceEvent.GATEWAYSENDER_STOP, this);
  }
  
  /**
   * Has a reference to a GatewayEventImpl and has a timeout value.
   */
  public static class EventWrapper  {
    /**
     * Timeout events received from secondary after 5 minutes by default.
     */
    static private final int EVENT_TIMEOUT
      = Integer.getInteger("Gateway.EVENT_TIMEOUT", 5 * 60 * 1000).intValue();
    public final long timeout;
    public final GatewaySenderEventImpl event;
    public EventWrapper(GatewaySenderEventImpl e) {
      this.event = e;
      this.timeout = System.currentTimeMillis() + EVENT_TIMEOUT;
    }
  }
  
  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("SerialGatewaySender{");
    sb.append("id=" + getId());
    sb.append(",remoteDsId="+ getRemoteDSId());
    sb.append(",isRunning ="+ isRunning());
    sb.append(",isPrimary ="+ isPrimary());
    sb.append("}");
    return sb.toString();
  }
 
  @Override
  public void fillInProfile(Profile profile) {
    assert profile instanceof GatewaySenderProfile;
    GatewaySenderProfile pf = (GatewaySenderProfile)profile;
    pf.Id = getId();
    pf.startTime = getStartTime();
    pf.remoteDSId = getRemoteDSId();
    pf.isRunning = isRunning();
    pf.isPrimary = isPrimary();
    pf.isParallel = false;
    pf.isBatchConflationEnabled = isBatchConflationEnabled();
    pf.isPersistenceEnabled = isPersistenceEnabled();
    pf.alertThreshold = getAlertThreshold();
    pf.manualStart = isManualStart();
    for (com.gemstone.gemfire.cache.wan.GatewayEventFilter filter : getGatewayEventFilters()) {
      pf.eventFiltersClassNames.add(filter.getClass().getName());
    }
    for (GatewayTransportFilter filter : getGatewayTransportFilters()) {
      pf.transFiltersClassNames.add(filter.getClass().getName());
    }
    for (AsyncEventListener listener : getAsyncEventListeners()) {
      pf.senderEventListenerClassNames.add(listener.getClass().getName());
    }
    pf.isDiskSynchronous = isDiskSynchronous();
    pf.dispatcherThreads = getDispatcherThreads();
    pf.orderPolicy = getOrderPolicy();
    pf.serverLocation = this.getServerLocation(); 
  }

  @Override
  protected void setModifiedEventId(EntryEventImpl clonedEvent) {
    // Nothing to do in this case
  }

  public Object getLockForConcurrentDispatcher() {
    return this.lockForConcurrentDispatcher;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy