0001: /*
0002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
0003: * notice. All rights reserved.
0004: */
0005: package com.tc.objectserver.impl;
0006:
0007: import bsh.EvalError;
0008: import bsh.Interpreter;
0009:
0010: import com.tc.async.api.SEDA;
0011: import com.tc.async.api.Sink;
0012: import com.tc.async.api.Stage;
0013: import com.tc.async.api.StageManager;
0014: import com.tc.async.impl.NullSink;
0015: import com.tc.config.schema.setup.ConfigurationSetupException;
0016: import com.tc.config.schema.setup.L2TVSConfigurationSetupManager;
0017: import com.tc.exception.TCRuntimeException;
0018: import com.tc.io.TCFile;
0019: import com.tc.io.TCFileImpl;
0020: import com.tc.io.TCRandomFileAccessImpl;
0021: import com.tc.l2.api.L2Coordinator;
0022: import com.tc.l2.ha.L2HACoordinator;
0023: import com.tc.l2.ha.L2HADisabledCooridinator;
0024: import com.tc.l2.state.StateManager;
0025: import com.tc.lang.TCThreadGroup;
0026: import com.tc.logging.CustomerLogging;
0027: import com.tc.logging.TCLogger;
0028: import com.tc.logging.TCLogging;
0029: import com.tc.management.L2LockStatsManager;
0030: import com.tc.management.L2LockStatsManagerImpl;
0031: import com.tc.management.L2Management;
0032: import com.tc.management.beans.L2State;
0033: import com.tc.management.beans.LockStatisticsMonitor;
0034: import com.tc.management.beans.LockStatisticsMonitorMBean;
0035: import com.tc.management.beans.TCDumper;
0036: import com.tc.management.beans.TCServerInfoMBean;
0037: import com.tc.management.remote.connect.ClientConnectEventHandler;
0038: import com.tc.management.remote.protocol.terracotta.ClientTunnelingEventHandler;
0039: import com.tc.management.remote.protocol.terracotta.JmxRemoteTunnelMessage;
0040: import com.tc.management.remote.protocol.terracotta.L1JmxReady;
0041: import com.tc.net.NIOWorkarounds;
0042: import com.tc.net.TCSocketAddress;
0043: import com.tc.net.groups.Node;
0044: import com.tc.net.protocol.NetworkStackHarnessFactory;
0045: import com.tc.net.protocol.PlainNetworkStackHarnessFactory;
0046: import com.tc.net.protocol.delivery.OOOEventHandler;
0047: import com.tc.net.protocol.delivery.OOONetworkStackHarnessFactory;
0048: import com.tc.net.protocol.delivery.OnceAndOnlyOnceProtocolNetworkLayerFactoryImpl;
0049: import com.tc.net.protocol.tcm.CommunicationsManager;
0050: import com.tc.net.protocol.tcm.CommunicationsManagerImpl;
0051: import com.tc.net.protocol.tcm.HydrateHandler;
0052: import com.tc.net.protocol.tcm.NetworkListener;
0053: import com.tc.net.protocol.tcm.NullMessageMonitor;
0054: import com.tc.net.protocol.tcm.TCMessageType;
0055: import com.tc.net.protocol.transport.ConnectionIDFactory;
0056: import com.tc.net.protocol.transport.ConnectionPolicy;
0057: import com.tc.object.cache.CacheConfigImpl;
0058: import com.tc.object.cache.CacheManager;
0059: import com.tc.object.cache.EvictionPolicy;
0060: import com.tc.object.cache.LFUConfigImpl;
0061: import com.tc.object.cache.LFUEvictionPolicy;
0062: import com.tc.object.cache.LRUEvictionPolicy;
0063: import com.tc.object.cache.NullCache;
0064: import com.tc.object.config.schema.NewL2DSOConfig;
0065: import com.tc.object.config.schema.PersistenceMode;
0066: import com.tc.object.msg.AcknowledgeTransactionMessageImpl;
0067: import com.tc.object.msg.BatchTransactionAcknowledgeMessageImpl;
0068: import com.tc.object.msg.BroadcastTransactionMessageImpl;
0069: import com.tc.object.msg.ClientHandshakeAckMessageImpl;
0070: import com.tc.object.msg.ClientHandshakeMessageImpl;
0071: import com.tc.object.msg.ClusterMembershipMessage;
0072: import com.tc.object.msg.CommitTransactionMessageImpl;
0073: import com.tc.object.msg.CompletedTransactionLowWaterMarkMessage;
0074: import com.tc.object.msg.JMXMessage;
0075: import com.tc.object.msg.LockRequestMessage;
0076: import com.tc.object.msg.LockResponseMessage;
0077: import com.tc.object.msg.LockStatisticsResponseMessage;
0078: import com.tc.object.msg.MessageRecycler;
0079: import com.tc.object.msg.ObjectIDBatchRequestMessage;
0080: import com.tc.object.msg.ObjectIDBatchRequestResponseMessage;
0081: import com.tc.object.msg.ObjectsNotFoundMessage;
0082: import com.tc.object.msg.RequestManagedObjectMessageImpl;
0083: import com.tc.object.msg.RequestManagedObjectResponseMessage;
0084: import com.tc.object.msg.RequestRootMessageImpl;
0085: import com.tc.object.msg.RequestRootResponseMessage;
0086: import com.tc.object.net.ChannelStats;
0087: import com.tc.object.net.ChannelStatsImpl;
0088: import com.tc.object.net.DSOChannelManager;
0089: import com.tc.object.net.DSOChannelManagerImpl;
0090: import com.tc.object.net.DSOChannelManagerMBean;
0091: import com.tc.object.session.NullSessionManager;
0092: import com.tc.object.session.SessionManager;
0093: import com.tc.object.session.SessionProvider;
0094: import com.tc.objectserver.DSOApplicationEvents;
0095: import com.tc.objectserver.api.ObjectManagerMBean;
0096: import com.tc.objectserver.api.ObjectRequestManager;
0097: import com.tc.objectserver.core.api.DSOGlobalServerStats;
0098: import com.tc.objectserver.core.api.DSOGlobalServerStatsImpl;
0099: import com.tc.objectserver.core.api.ServerConfigurationContext;
0100: import com.tc.objectserver.core.impl.MarkAndSweepGarbageCollector;
0101: import com.tc.objectserver.core.impl.ServerConfigurationContextImpl;
0102: import com.tc.objectserver.core.impl.ServerManagementContext;
0103: import com.tc.objectserver.gtx.ServerGlobalTransactionManager;
0104: import com.tc.objectserver.gtx.ServerGlobalTransactionManagerImpl;
0105: import com.tc.objectserver.handler.ApplyCompleteTransactionHandler;
0106: import com.tc.objectserver.handler.ApplyTransactionChangeHandler;
0107: import com.tc.objectserver.handler.BroadcastChangeHandler;
0108: import com.tc.objectserver.handler.ChannelLifeCycleHandler;
0109: import com.tc.objectserver.handler.ClientHandshakeHandler;
0110: import com.tc.objectserver.handler.ClientLockStatisticsHandler;
0111: import com.tc.objectserver.handler.CommitTransactionChangeHandler;
0112: import com.tc.objectserver.handler.GlobalTransactionIDBatchRequestHandler;
0113: import com.tc.objectserver.handler.JMXEventsHandler;
0114: import com.tc.objectserver.handler.ManagedObjectFaultHandler;
0115: import com.tc.objectserver.handler.ManagedObjectFlushHandler;
0116: import com.tc.objectserver.handler.ManagedObjectRequestHandler;
0117: import com.tc.objectserver.handler.ProcessTransactionHandler;
0118: import com.tc.objectserver.handler.RecallObjectsHandler;
0119: import com.tc.objectserver.handler.RequestLockUnLockHandler;
0120: import com.tc.objectserver.handler.RequestObjectIDBatchHandler;
0121: import com.tc.objectserver.handler.RequestRootHandler;
0122: import com.tc.objectserver.handler.RespondToObjectRequestHandler;
0123: import com.tc.objectserver.handler.RespondToRequestLockHandler;
0124: import com.tc.objectserver.handler.TransactionAcknowledgementHandler;
0125: import com.tc.objectserver.handler.TransactionLookupHandler;
0126: import com.tc.objectserver.handler.TransactionLowWaterMarkHandler;
0127: import com.tc.objectserver.handshakemanager.ServerClientHandshakeManager;
0128: import com.tc.objectserver.l1.api.ClientStateManager;
0129: import com.tc.objectserver.l1.impl.ClientStateManagerImpl;
0130: import com.tc.objectserver.l1.impl.TransactionAcknowledgeAction;
0131: import com.tc.objectserver.l1.impl.TransactionAcknowledgeActionImpl;
0132: import com.tc.objectserver.lockmanager.api.LockManager;
0133: import com.tc.objectserver.lockmanager.api.LockManagerMBean;
0134: import com.tc.objectserver.lockmanager.impl.LockManagerImpl;
0135: import com.tc.objectserver.managedobject.ManagedObjectChangeListenerProviderImpl;
0136: import com.tc.objectserver.managedobject.ManagedObjectStateFactory;
0137: import com.tc.objectserver.persistence.api.ClientStatePersistor;
0138: import com.tc.objectserver.persistence.api.ManagedObjectStore;
0139: import com.tc.objectserver.persistence.api.PersistenceTransactionProvider;
0140: import com.tc.objectserver.persistence.api.Persistor;
0141: import com.tc.objectserver.persistence.api.TransactionPersistor;
0142: import com.tc.objectserver.persistence.api.TransactionStore;
0143: import com.tc.objectserver.persistence.impl.InMemoryPersistor;
0144: import com.tc.objectserver.persistence.impl.InMemorySequenceProvider;
0145: import com.tc.objectserver.persistence.impl.NullPersistenceTransactionProvider;
0146: import com.tc.objectserver.persistence.impl.NullTransactionPersistor;
0147: import com.tc.objectserver.persistence.impl.TransactionStoreImpl;
0148: import com.tc.objectserver.persistence.sleepycat.ConnectionIDFactoryImpl;
0149: import com.tc.objectserver.persistence.sleepycat.CustomSerializationAdapterFactory;
0150: import com.tc.objectserver.persistence.sleepycat.DBEnvironment;
0151: import com.tc.objectserver.persistence.sleepycat.DBException;
0152: import com.tc.objectserver.persistence.sleepycat.SerializationAdapterFactory;
0153: import com.tc.objectserver.persistence.sleepycat.SleepycatPersistor;
0154: import com.tc.objectserver.persistence.sleepycat.TCDatabaseException;
0155: import com.tc.objectserver.tx.CommitTransactionMessageRecycler;
0156: import com.tc.objectserver.tx.CommitTransactionMessageToTransactionBatchReader;
0157: import com.tc.objectserver.tx.ServerTransactionManagerConfig;
0158: import com.tc.objectserver.tx.ServerTransactionManagerImpl;
0159: import com.tc.objectserver.tx.TransactionBatchManager;
0160: import com.tc.objectserver.tx.TransactionBatchManagerImpl;
0161: import com.tc.objectserver.tx.TransactionSequencer;
0162: import com.tc.objectserver.tx.TransactionalObjectManagerImpl;
0163: import com.tc.objectserver.tx.TransactionalStagesCoordinatorImpl;
0164: import com.tc.properties.TCProperties;
0165: import com.tc.properties.TCPropertiesImpl;
0166: import com.tc.stats.counter.sampled.SampledCounter;
0167: import com.tc.stats.counter.sampled.SampledCounterConfig;
0168: import com.tc.stats.counter.sampled.SampledCounterManager;
0169: import com.tc.stats.counter.sampled.SampledCounterManagerImpl;
0170: import com.tc.util.Assert;
0171: import com.tc.util.ProductInfo;
0172: import com.tc.util.SequenceValidator;
0173: import com.tc.util.StartupLock;
0174: import com.tc.util.TCTimeoutException;
0175: import com.tc.util.TCTimerImpl;
0176: import com.tc.util.io.TCFileUtils;
0177: import com.tc.util.sequence.BatchSequence;
0178: import com.tc.util.sequence.MutableSequence;
0179: import com.tc.util.sequence.Sequence;
0180: import com.tc.util.startuplock.FileNotCreatedException;
0181: import com.tc.util.startuplock.LocationNotCreatedException;
0182:
0183: import java.io.File;
0184: import java.io.IOException;
0185: import java.util.Collections;
0186: import java.util.HashMap;
0187: import java.util.Properties;
0188: import java.util.Set;
0189:
0190: import javax.management.MBeanServer;
0191: import javax.management.NotCompliantMBeanException;
0192:
0193: /**
0194: * Startup and shutdown point. Builds and starts the server
0195: *
0196: * @author steve
0197: */
0198: public class DistributedObjectServer extends SEDA implements TCDumper {
0199: private final ConnectionPolicy connectionPolicy;
0200:
0201: private static final TCLogger logger = CustomerLogging
0202: .getDSOGenericLogger();
0203: private static final TCLogger consoleLogger = CustomerLogging
0204: .getConsoleLogger();
0205:
0206: private final L2TVSConfigurationSetupManager configSetupManager;
0207: private final Sink httpSink;
0208: private NetworkListener l1Listener;
0209: private CommunicationsManager communicationsManager;
0210: private ServerConfigurationContext context;
0211: private ObjectManagerImpl objectManager;
0212: private TransactionalObjectManagerImpl txnObjectManager;
0213: private SampledCounterManager sampledCounterManager;
0214: private LockManager lockManager;
0215: private ServerManagementContext managementContext;
0216: private StartupLock startupLock;
0217:
0218: private ClientStateManagerImpl clientStateManager;
0219:
0220: private ManagedObjectStore objectStore;
0221: private Persistor persistor;
0222: private ServerTransactionManagerImpl transactionManager;
0223:
0224: private CacheManager cacheManager;
0225:
0226: private final TCServerInfoMBean tcServerInfoMBean;
0227: private final L2State l2State;
0228: private L2Management l2Management;
0229: private L2Coordinator l2Coordinator;
0230:
0231: private TCProperties l2Properties;
0232:
0233: private ConnectionIDFactoryImpl connectionIdFactory;
0234:
0235: private LockStatisticsMonitorMBean lockStatisticsMBean;
0236:
0237: // used by a test
0238: public DistributedObjectServer(
0239: L2TVSConfigurationSetupManager configSetupManager,
0240: TCThreadGroup threadGroup,
0241: ConnectionPolicy connectionPolicy,
0242: TCServerInfoMBean tcServerInfoMBean) {
0243: this (configSetupManager, threadGroup, connectionPolicy,
0244: new NullSink(), tcServerInfoMBean, new L2State());
0245: }
0246:
0247: public DistributedObjectServer(
0248: L2TVSConfigurationSetupManager configSetupManager,
0249: TCThreadGroup threadGroup,
0250: ConnectionPolicy connectionPolicy, Sink httpSink,
0251: TCServerInfoMBean tcServerInfoMBean, L2State l2State) {
0252: super (threadGroup);
0253:
0254: // This assertion is here because we want to assume that all threads spawned by the server (including any created in
0255: // 3rd party libs) inherit their thread group from the current thread . Consider this before removing the assertion.
0256: // Even in tests, we probably don't want different thread group configurations
0257: Assert.assertEquals(threadGroup, Thread.currentThread()
0258: .getThreadGroup());
0259:
0260: this .configSetupManager = configSetupManager;
0261: this .connectionPolicy = connectionPolicy;
0262: this .httpSink = httpSink;
0263: this .tcServerInfoMBean = tcServerInfoMBean;
0264: this .l2State = l2State;
0265: }
0266:
0267: public void dump() {
0268: if (this .lockManager != null) {
0269: this .lockManager.dump();
0270: }
0271:
0272: if (this .objectManager != null) {
0273: this .objectManager.dump();
0274: }
0275:
0276: if (this .txnObjectManager != null) {
0277: this .txnObjectManager.dump();
0278: }
0279:
0280: if (this .transactionManager != null) {
0281: this .transactionManager.dump();
0282: }
0283: }
0284:
0285: public synchronized void start() throws IOException,
0286: TCDatabaseException, LocationNotCreatedException,
0287: FileNotCreatedException {
0288:
0289: L2LockStatsManager lockStatsManager = new L2LockStatsManagerImpl();
0290: this .lockStatisticsMBean = new LockStatisticsMonitor(
0291: lockStatsManager);
0292:
0293: try {
0294: startJMXServer();
0295: } catch (Exception e) {
0296: String msg = "Unable to start the JMX server. Do you have another Terracotta Server running?";
0297: consoleLogger.error(msg);
0298: logger.error(msg, e);
0299: System.exit(-1);
0300: }
0301:
0302: NIOWorkarounds.solaris10Workaround();
0303:
0304: configSetupManager.commonl2Config().changesInItemIgnored(
0305: configSetupManager.commonl2Config().dataPath());
0306: NewL2DSOConfig l2DSOConfig = configSetupManager.dsoL2Config();
0307: l2DSOConfig.changesInItemIgnored(l2DSOConfig.persistenceMode());
0308: PersistenceMode persistenceMode = (PersistenceMode) l2DSOConfig
0309: .persistenceMode().getObject();
0310:
0311: final boolean swapEnabled = true; // 2006-01-31 andrew -- no longer possible to use in-memory only; DSO folks say
0312: // it's broken
0313: final boolean persistent = persistenceMode
0314: .equals(PersistenceMode.PERMANENT_STORE);
0315:
0316: TCFile location = new TCFileImpl(this .configSetupManager
0317: .commonl2Config().dataPath().getFile());
0318: startupLock = new StartupLock(location);
0319:
0320: if (!startupLock.canProceed(new TCRandomFileAccessImpl(),
0321: persistent)) {
0322: consoleLogger
0323: .error("Another L2 process is using the directory "
0324: + location + " as data directory.");
0325: if (!persistent) {
0326: consoleLogger
0327: .error("This is not allowed with persistence mode set to temporary-swap-only.");
0328: }
0329: consoleLogger.error("Exiting...");
0330: System.exit(1);
0331: }
0332:
0333: int maxStageSize = 5000;
0334:
0335: StageManager stageManager = getStageManager();
0336: SessionManager sessionManager = new NullSessionManager();
0337: SessionProvider sessionProvider = (SessionProvider) sessionManager;
0338: l2Properties = TCPropertiesImpl.getProperties()
0339: .getPropertiesFor("l2");
0340:
0341: EvictionPolicy swapCache;
0342: final ClientStatePersistor clientStateStore;
0343: final PersistenceTransactionProvider persistenceTransactionProvider;
0344: final TransactionPersistor transactionPersistor;
0345: final Sequence globalTransactionIDSequence;
0346: logger.debug("server swap enabled: " + swapEnabled);
0347: final ManagedObjectChangeListenerProviderImpl managedObjectChangeListenerProvider = new ManagedObjectChangeListenerProviderImpl();
0348: if (swapEnabled) {
0349: File dbhome = new File(configSetupManager.commonl2Config()
0350: .dataPath().getFile(), "objectdb");
0351: logger.debug("persistent: " + persistent);
0352: if (!persistent) {
0353: if (dbhome.exists()) {
0354: logger.debug("deleting persistence database...");
0355: TCFileUtils.forceDelete(dbhome, "jdb");
0356: logger.debug("persistence database deleted.");
0357: }
0358: }
0359: logger.debug("persistence database home: " + dbhome);
0360:
0361: DBEnvironment dbenv = new DBEnvironment(persistent, dbhome,
0362: l2Properties.getPropertiesFor("berkeleydb")
0363: .addAllPropertiesTo(new Properties()));
0364: SerializationAdapterFactory serializationAdapterFactory = new CustomSerializationAdapterFactory();
0365: persistor = new SleepycatPersistor(TCLogging
0366: .getLogger(SleepycatPersistor.class), dbenv,
0367: serializationAdapterFactory);
0368: /*
0369: * This commented code is for replacing SleepyCat with MemoryDataStore as an in-memory DB for testing purpose. You
0370: * need to include MemoryDataStore in tc.jar and enable with tc.properties l2.memorystore.enabled=true. boolean
0371: * useMemoryStore = false; if (l2Properties.getProperty("memorystore.enabled", false) != null) { useMemoryStore =
0372: * l2Properties.getBoolean("memorystore.enabled"); } if (useMemoryStore) { persistor = new
0373: * MemoryStorePersistor(TCLogging.getLogger(MemoryStorePersistor.class)); }
0374: */
0375:
0376: String cachePolicy = l2Properties.getProperty(
0377: "objectmanager.cachePolicy").toUpperCase();
0378: if (cachePolicy.equals("LRU")) {
0379: swapCache = new LRUEvictionPolicy(-1);
0380: } else if (cachePolicy.equals("LFU")) {
0381: swapCache = new LFUEvictionPolicy(-1,
0382: new LFUConfigImpl(l2Properties
0383: .getPropertiesFor("lfu")));
0384: } else {
0385: throw new AssertionError(
0386: "Unknown Cache Policy : "
0387: + cachePolicy
0388: + " Accepted Values are : <LRU>/<LFU> Please check tc.properties");
0389: }
0390: objectStore = new PersistentManagedObjectStore(persistor
0391: .getManagedObjectPersistor());
0392: } else {
0393: persistor = new InMemoryPersistor();
0394: swapCache = new NullCache();
0395: objectStore = new InMemoryManagedObjectStore(new HashMap());
0396: }
0397:
0398: persistenceTransactionProvider = persistor
0399: .getPersistenceTransactionProvider();
0400: PersistenceTransactionProvider transactionStorePTP;
0401: MutableSequence gidSequence;
0402: if (persistent) {
0403: gidSequence = persistor.getGlobalTransactionIDSequence();
0404:
0405: transactionPersistor = persistor.getTransactionPersistor();
0406: transactionStorePTP = persistenceTransactionProvider;
0407: } else {
0408: gidSequence = new InMemorySequenceProvider();
0409:
0410: transactionPersistor = new NullTransactionPersistor();
0411: transactionStorePTP = new NullPersistenceTransactionProvider();
0412: }
0413:
0414: GlobalTransactionIDBatchRequestHandler gidSequenceProvider = new GlobalTransactionIDBatchRequestHandler(
0415: gidSequence);
0416: Stage requestBatchStage = stageManager
0417: .createStage(
0418: ServerConfigurationContext.REQUEST_BATCH_GLOBAL_TRANSACTION_ID_SEQUENCE_STAGE,
0419: gidSequenceProvider, 1, maxStageSize);
0420: gidSequenceProvider.setRequestBatchSink(requestBatchStage
0421: .getSink());
0422: globalTransactionIDSequence = new BatchSequence(
0423: gidSequenceProvider, 10000);
0424:
0425: clientStateStore = persistor.getClientStatePersistor();
0426:
0427: ManagedObjectStateFactory.createInstance(
0428: managedObjectChangeListenerProvider, persistor);
0429:
0430: final NetworkStackHarnessFactory networkStackHarnessFactory;
0431: final boolean useOOOLayer = TCPropertiesImpl.getProperties()
0432: .getBoolean("l1.reconnect.enabled");
0433: if (useOOOLayer) {
0434: final Stage oooStage = stageManager.createStage(
0435: "OOONetStage", new OOOEventHandler(), 1,
0436: maxStageSize);
0437: networkStackHarnessFactory = new OOONetworkStackHarnessFactory(
0438: new OnceAndOnlyOnceProtocolNetworkLayerFactoryImpl(),
0439: oooStage.getSink());
0440: } else {
0441: networkStackHarnessFactory = new PlainNetworkStackHarnessFactory();
0442: }
0443: communicationsManager = new CommunicationsManagerImpl(
0444: new NullMessageMonitor(), networkStackHarnessFactory,
0445: connectionPolicy);
0446:
0447: final DSOApplicationEvents appEvents;
0448: try {
0449: appEvents = new DSOApplicationEvents();
0450: } catch (NotCompliantMBeanException ncmbe) {
0451: throw new TCRuntimeException(
0452: "Unable to construct the "
0453: + DSOApplicationEvents.class.getName()
0454: + " MBean; this is a programming error. Please go fix that class.",
0455: ncmbe);
0456: }
0457:
0458: clientStateManager = new ClientStateManagerImpl(TCLogging
0459: .getLogger(ClientStateManager.class));
0460:
0461: l2DSOConfig.changesInItemIgnored(l2DSOConfig
0462: .garbageCollectionEnabled());
0463: boolean gcEnabled = l2DSOConfig.garbageCollectionEnabled()
0464: .getBoolean();
0465: logger.debug("GC enabled: " + gcEnabled);
0466:
0467: l2DSOConfig.changesInItemIgnored(l2DSOConfig
0468: .garbageCollectionInterval());
0469: long gcInterval = l2DSOConfig.garbageCollectionInterval()
0470: .getInt();
0471: if (gcEnabled)
0472: logger.debug("GC interval: " + gcInterval + " seconds");
0473:
0474: l2DSOConfig.changesInItemIgnored(l2DSOConfig
0475: .garbageCollectionVerbose());
0476: boolean verboseGC = l2DSOConfig.garbageCollectionVerbose()
0477: .getBoolean();
0478: if (gcEnabled)
0479: logger.debug("Verbose GC enabled: " + verboseGC);
0480: sampledCounterManager = new SampledCounterManagerImpl();
0481: SampledCounter objectCreationRate = sampledCounterManager
0482: .createCounter(new SampledCounterConfig(1, 900, true,
0483: 0L));
0484: SampledCounter objectFaultRate = sampledCounterManager
0485: .createCounter(new SampledCounterConfig(1, 900, true,
0486: 0L));
0487: ObjectManagerStatsImpl objMgrStats = new ObjectManagerStatsImpl(
0488: objectCreationRate, objectFaultRate);
0489:
0490: SequenceValidator sequenceValidator = new SequenceValidator(0);
0491: ManagedObjectFaultHandler managedObjectFaultHandler = new ManagedObjectFaultHandler();
0492: // Server initiated request processing queues shouldn't have any max queue size.
0493: Stage faultManagedObjectStage = stageManager.createStage(
0494: ServerConfigurationContext.MANAGED_OBJECT_FAULT_STAGE,
0495: managedObjectFaultHandler, l2Properties
0496: .getInt("seda.faultstage.threads"), -1);
0497: ManagedObjectFlushHandler managedObjectFlushHandler = new ManagedObjectFlushHandler();
0498: Stage flushManagedObjectStage = stageManager
0499: .createStage(
0500: ServerConfigurationContext.MANAGED_OBJECT_FLUSH_STAGE,
0501: managedObjectFlushHandler,
0502: (persistent ? 1 : l2Properties
0503: .getInt("seda.flushstage.threads")), -1);
0504:
0505: TCProperties objManagerProperties = l2Properties
0506: .getPropertiesFor("objectmanager");
0507:
0508: ObjectManagerConfig objectManagerConfig = new ObjectManagerConfig(
0509: gcInterval * 1000, gcEnabled, verboseGC, persistent,
0510: objManagerProperties.getInt("deleteBatchSize"));
0511: objectManager = new ObjectManagerImpl(objectManagerConfig,
0512: getThreadGroup(), clientStateManager, objectStore,
0513: swapCache, persistenceTransactionProvider,
0514: faultManagedObjectStage.getSink(),
0515: flushManagedObjectStage.getSink());
0516: objectManager.setStatsListener(objMgrStats);
0517: objectManager
0518: .setGarbageCollector(new MarkAndSweepGarbageCollector(
0519: objectManager, clientStateManager, verboseGC));
0520: managedObjectChangeListenerProvider.setListener(objectManager);
0521: l2Management.findObjectManagementMonitorMBean()
0522: .registerGCController(
0523: new GCComptrollerImpl(objectManagerConfig,
0524: objectManager.getGarbageCollector()));
0525:
0526: TCProperties cacheManagerProperties = l2Properties
0527: .getPropertiesFor("cachemanager");
0528: if (cacheManagerProperties.getBoolean("enabled")) {
0529: cacheManager = new CacheManager(objectManager,
0530: new CacheConfigImpl(cacheManagerProperties),
0531: getThreadGroup());
0532: if (logger.isDebugEnabled()) {
0533: logger.debug("CacheManager Enabled : " + cacheManager);
0534: }
0535: } else {
0536: logger.warn("CacheManager is Disabled");
0537: }
0538:
0539: connectionIdFactory = new ConnectionIDFactoryImpl(
0540: clientStateStore);
0541:
0542: l2DSOConfig.changesInItemIgnored(l2DSOConfig.listenPort());
0543: int serverPort = l2DSOConfig.listenPort().getInt();
0544: l1Listener = communicationsManager.createListener(
0545: sessionProvider, new TCSocketAddress(
0546: TCSocketAddress.WILDCARD_ADDR, serverPort),
0547: true, connectionIdFactory, httpSink);
0548:
0549: ClientTunnelingEventHandler cteh = new ClientTunnelingEventHandler();
0550:
0551: ProductInfo pInfo = ProductInfo.getInstance();
0552: DSOChannelManager channelManager = new DSOChannelManagerImpl(
0553: l1Listener.getChannelManager(), pInfo.buildVersion());
0554: channelManager.addEventListener(cteh);
0555: channelManager.addEventListener(connectionIdFactory);
0556:
0557: ChannelStats channelStats = new ChannelStatsImpl(
0558: sampledCounterManager, channelManager);
0559:
0560: lockManager = new LockManagerImpl(channelManager,
0561: lockStatsManager);
0562: ObjectInstanceMonitorImpl instanceMonitor = new ObjectInstanceMonitorImpl();
0563: TransactionBatchManager transactionBatchManager = new TransactionBatchManagerImpl();
0564: TransactionAcknowledgeAction taa = new TransactionAcknowledgeActionImpl(
0565: channelManager, transactionBatchManager);
0566: SampledCounter globalTxnCounter = sampledCounterManager
0567: .createCounter(new SampledCounterConfig(1, 300, true,
0568: 0L));
0569:
0570: final TransactionStore transactionStore = new TransactionStoreImpl(
0571: transactionPersistor, globalTransactionIDSequence);
0572: ServerGlobalTransactionManager gtxm = new ServerGlobalTransactionManagerImpl(
0573: sequenceValidator, transactionStore,
0574: transactionStorePTP, gidSequenceProvider,
0575: globalTransactionIDSequence);
0576:
0577: TransactionalStagesCoordinatorImpl txnStageCoordinator = new TransactionalStagesCoordinatorImpl(
0578: stageManager);
0579: txnObjectManager = new TransactionalObjectManagerImpl(
0580: objectManager, new TransactionSequencer(), gtxm,
0581: txnStageCoordinator);
0582: objectManager.setTransactionalObjectManager(txnObjectManager);
0583: transactionManager = new ServerTransactionManagerImpl(gtxm,
0584: transactionStore, lockManager, clientStateManager,
0585: objectManager, txnObjectManager, taa, globalTxnCounter,
0586: channelStats,
0587: new ServerTransactionManagerConfig(l2Properties
0588: .getPropertiesFor("transactionmanager")));
0589:
0590: MessageRecycler recycler = new CommitTransactionMessageRecycler(
0591: transactionManager);
0592: ObjectRequestManager objectRequestManager = new ObjectRequestManagerImpl(
0593: objectManager, transactionManager);
0594:
0595: stageManager.createStage(
0596: ServerConfigurationContext.TRANSACTION_LOOKUP_STAGE,
0597: new TransactionLookupHandler(), 1, maxStageSize);
0598:
0599: // Lookup stage should never be blocked trying to add to apply stage
0600: stageManager.createStage(
0601: ServerConfigurationContext.APPLY_CHANGES_STAGE,
0602: new ApplyTransactionChangeHandler(instanceMonitor,
0603: transactionManager), 1, -1);
0604:
0605: stageManager.createStage(
0606: ServerConfigurationContext.APPLY_COMPLETE_STAGE,
0607: new ApplyCompleteTransactionHandler(), 1, maxStageSize);
0608:
0609: // Server initiated request processing stages should not be bounded
0610: stageManager.createStage(
0611: ServerConfigurationContext.RECALL_OBJECTS_STAGE,
0612: new RecallObjectsHandler(), 1, -1);
0613:
0614: int commitThreads = (persistent ? l2Properties
0615: .getInt("seda.commitstage.threads") : 1);
0616: stageManager
0617: .createStage(
0618: ServerConfigurationContext.COMMIT_CHANGES_STAGE,
0619: new CommitTransactionChangeHandler(
0620: transactionStorePTP), commitThreads,
0621: maxStageSize);
0622:
0623: txnStageCoordinator.lookUpSinks();
0624:
0625: Stage processTx = stageManager.createStage(
0626: ServerConfigurationContext.PROCESS_TRANSACTION_STAGE,
0627: new ProcessTransactionHandler(transactionBatchManager,
0628: sequenceValidator, recycler), 1, maxStageSize);
0629:
0630: Stage rootRequest = stageManager.createStage(
0631: ServerConfigurationContext.MANAGED_ROOT_REQUEST_STAGE,
0632: new RequestRootHandler(), 1, maxStageSize);
0633:
0634: stageManager.createStage(
0635: ServerConfigurationContext.BROADCAST_CHANGES_STAGE,
0636: new BroadcastChangeHandler(), 1, maxStageSize);
0637: Stage respondToLockRequestStage = stageManager
0638: .createStage(
0639: ServerConfigurationContext.RESPOND_TO_LOCK_REQUEST_STAGE,
0640: new RespondToRequestLockHandler(), 1,
0641: maxStageSize);
0642: Stage requestLock = stageManager.createStage(
0643: ServerConfigurationContext.REQUEST_LOCK_STAGE,
0644: new RequestLockUnLockHandler(), 1, maxStageSize);
0645: ChannelLifeCycleHandler channelLifeCycleHandler = new ChannelLifeCycleHandler(
0646: communicationsManager, transactionManager,
0647: transactionBatchManager, channelManager);
0648: stageManager.createStage(
0649: ServerConfigurationContext.CHANNEL_LIFE_CYCLE_STAGE,
0650: channelLifeCycleHandler, 1, maxStageSize);
0651: channelManager.addEventListener(channelLifeCycleHandler);
0652:
0653: SampledCounter globalObjectFaultCounter = sampledCounterManager
0654: .createCounter(new SampledCounterConfig(1, 300, true,
0655: 0L));
0656: SampledCounter globalObjectFlushCounter = sampledCounterManager
0657: .createCounter(new SampledCounterConfig(1, 300, true,
0658: 0L));
0659: Stage objectRequest = stageManager
0660: .createStage(
0661: ServerConfigurationContext.MANAGED_OBJECT_REQUEST_STAGE,
0662: new ManagedObjectRequestHandler(
0663: globalObjectFaultCounter,
0664: globalObjectFlushCounter,
0665: objectRequestManager), 1, maxStageSize);
0666: stageManager
0667: .createStage(
0668: ServerConfigurationContext.RESPOND_TO_OBJECT_REQUEST_STAGE,
0669: new RespondToObjectRequestHandler(), 4,
0670: maxStageSize);
0671: Stage oidRequest = stageManager
0672: .createStage(
0673: ServerConfigurationContext.OBJECT_ID_BATCH_REQUEST_STAGE,
0674: new RequestObjectIDBatchHandler(objectStore),
0675: 1, maxStageSize);
0676: Stage transactionAck = stageManager
0677: .createStage(
0678: ServerConfigurationContext.TRANSACTION_ACKNOWLEDGEMENT_STAGE,
0679: new TransactionAcknowledgementHandler(), 1,
0680: maxStageSize);
0681: Stage clientHandshake = stageManager.createStage(
0682: ServerConfigurationContext.CLIENT_HANDSHAKE_STAGE,
0683: new ClientHandshakeHandler(), 1, maxStageSize);
0684: Stage hydrateStage = stageManager.createStage(
0685: ServerConfigurationContext.HYDRATE_MESSAGE_SINK,
0686: new HydrateHandler(), 1, maxStageSize);
0687: final Stage txnLwmStage = stageManager
0688: .createStage(
0689: ServerConfigurationContext.TRANSACTION_LOWWATERMARK_STAGE,
0690: new TransactionLowWaterMarkHandler(gtxm), 1,
0691: maxStageSize);
0692:
0693: Stage jmxEventsStage = stageManager.createStage(
0694: ServerConfigurationContext.JMX_EVENTS_STAGE,
0695: new JMXEventsHandler(appEvents), 1, maxStageSize);
0696:
0697: final Stage jmxRemoteConnectStage = stageManager.createStage(
0698: ServerConfigurationContext.JMXREMOTE_CONNECT_STAGE,
0699: new ClientConnectEventHandler(), 1, maxStageSize);
0700: cteh.setConnectStageSink(jmxRemoteConnectStage.getSink());
0701: final Stage jmxRemoteTunnelStage = stageManager.createStage(
0702: ServerConfigurationContext.JMXREMOTE_TUNNEL_STAGE,
0703: cteh, 1, maxStageSize);
0704:
0705: final Stage clientLockStatisticsStage = stageManager
0706: .createStage(
0707: ServerConfigurationContext.CLIENT_LOCK_STATISTICS_STAGE,
0708: new ClientLockStatisticsHandler(
0709: lockStatsManager), 1, 1);
0710:
0711: l1Listener.addClassMapping(
0712: TCMessageType.BATCH_TRANSACTION_ACK_MESSAGE,
0713: BatchTransactionAcknowledgeMessageImpl.class);
0714: l1Listener.addClassMapping(TCMessageType.REQUEST_ROOT_MESSAGE,
0715: RequestRootMessageImpl.class);
0716: l1Listener.addClassMapping(TCMessageType.LOCK_REQUEST_MESSAGE,
0717: LockRequestMessage.class);
0718: l1Listener.addClassMapping(TCMessageType.LOCK_RESPONSE_MESSAGE,
0719: LockResponseMessage.class);
0720: l1Listener.addClassMapping(TCMessageType.LOCK_RECALL_MESSAGE,
0721: LockResponseMessage.class);
0722: l1Listener.addClassMapping(
0723: TCMessageType.LOCK_QUERY_RESPONSE_MESSAGE,
0724: LockResponseMessage.class);
0725: l1Listener.addClassMapping(TCMessageType.LOCK_STAT_MESSAGE,
0726: LockResponseMessage.class);
0727: l1Listener.addClassMapping(
0728: TCMessageType.LOCK_STATISTICS_RESPONSE_MESSAGE,
0729: LockStatisticsResponseMessage.class);
0730: l1Listener.addClassMapping(
0731: TCMessageType.COMMIT_TRANSACTION_MESSAGE,
0732: CommitTransactionMessageImpl.class);
0733: l1Listener.addClassMapping(
0734: TCMessageType.REQUEST_ROOT_RESPONSE_MESSAGE,
0735: RequestRootResponseMessage.class);
0736: l1Listener.addClassMapping(
0737: TCMessageType.REQUEST_MANAGED_OBJECT_MESSAGE,
0738: RequestManagedObjectMessageImpl.class);
0739: l1Listener.addClassMapping(
0740: TCMessageType.REQUEST_MANAGED_OBJECT_RESPONSE_MESSAGE,
0741: RequestManagedObjectResponseMessage.class);
0742: l1Listener.addClassMapping(
0743: TCMessageType.OBJECTS_NOT_FOUND_RESPONSE_MESSAGE,
0744: ObjectsNotFoundMessage.class);
0745: l1Listener.addClassMapping(
0746: TCMessageType.BROADCAST_TRANSACTION_MESSAGE,
0747: BroadcastTransactionMessageImpl.class);
0748: l1Listener.addClassMapping(
0749: TCMessageType.OBJECT_ID_BATCH_REQUEST_MESSAGE,
0750: ObjectIDBatchRequestMessage.class);
0751: l1Listener.addClassMapping(
0752: TCMessageType.OBJECT_ID_BATCH_REQUEST_RESPONSE_MESSAGE,
0753: ObjectIDBatchRequestResponseMessage.class);
0754: l1Listener.addClassMapping(
0755: TCMessageType.ACKNOWLEDGE_TRANSACTION_MESSAGE,
0756: AcknowledgeTransactionMessageImpl.class);
0757: l1Listener.addClassMapping(
0758: TCMessageType.CLIENT_HANDSHAKE_MESSAGE,
0759: ClientHandshakeMessageImpl.class);
0760: l1Listener.addClassMapping(
0761: TCMessageType.CLIENT_HANDSHAKE_ACK_MESSAGE,
0762: ClientHandshakeAckMessageImpl.class);
0763: l1Listener.addClassMapping(TCMessageType.JMX_MESSAGE,
0764: JMXMessage.class);
0765: l1Listener.addClassMapping(
0766: TCMessageType.JMXREMOTE_MESSAGE_CONNECTION_MESSAGE,
0767: JmxRemoteTunnelMessage.class);
0768: l1Listener.addClassMapping(
0769: TCMessageType.CLUSTER_MEMBERSHIP_EVENT_MESSAGE,
0770: ClusterMembershipMessage.class);
0771: l1Listener.addClassMapping(
0772: TCMessageType.CLIENT_JMX_READY_MESSAGE,
0773: L1JmxReady.class);
0774: l1Listener
0775: .addClassMapping(
0776: TCMessageType.COMPLETED_TRANSACTION_LOWWATERMARK_MESSAGE,
0777: CompletedTransactionLowWaterMarkMessage.class);
0778:
0779: Sink hydrateSink = hydrateStage.getSink();
0780: l1Listener.routeMessageType(
0781: TCMessageType.COMMIT_TRANSACTION_MESSAGE, processTx
0782: .getSink(), hydrateSink);
0783: l1Listener.routeMessageType(TCMessageType.LOCK_REQUEST_MESSAGE,
0784: requestLock.getSink(), hydrateSink);
0785: l1Listener.routeMessageType(TCMessageType.REQUEST_ROOT_MESSAGE,
0786: rootRequest.getSink(), hydrateSink);
0787: l1Listener.routeMessageType(
0788: TCMessageType.REQUEST_MANAGED_OBJECT_MESSAGE,
0789: objectRequest.getSink(), hydrateSink);
0790: l1Listener.routeMessageType(
0791: TCMessageType.OBJECT_ID_BATCH_REQUEST_MESSAGE,
0792: oidRequest.getSink(), hydrateSink);
0793: l1Listener.routeMessageType(
0794: TCMessageType.ACKNOWLEDGE_TRANSACTION_MESSAGE,
0795: transactionAck.getSink(), hydrateSink);
0796: l1Listener.routeMessageType(
0797: TCMessageType.CLIENT_HANDSHAKE_MESSAGE, clientHandshake
0798: .getSink(), hydrateSink);
0799: l1Listener.routeMessageType(TCMessageType.JMX_MESSAGE,
0800: jmxEventsStage.getSink(), hydrateSink);
0801: l1Listener.routeMessageType(
0802: TCMessageType.JMXREMOTE_MESSAGE_CONNECTION_MESSAGE,
0803: jmxRemoteTunnelStage.getSink(), hydrateSink);
0804: l1Listener.routeMessageType(
0805: TCMessageType.CLIENT_JMX_READY_MESSAGE,
0806: jmxRemoteTunnelStage.getSink(), hydrateSink);
0807: l1Listener.routeMessageType(
0808: TCMessageType.LOCK_STATISTICS_RESPONSE_MESSAGE,
0809: clientLockStatisticsStage.getSink(), hydrateSink);
0810: l1Listener
0811: .routeMessageType(
0812: TCMessageType.COMPLETED_TRANSACTION_LOWWATERMARK_MESSAGE,
0813: txnLwmStage.getSink(), hydrateSink);
0814:
0815: l2DSOConfig.changesInItemIgnored(l2DSOConfig
0816: .clientReconnectWindow());
0817: long reconnectTimeout = l2DSOConfig.clientReconnectWindow()
0818: .getInt();
0819: logger.debug("Client Reconnect Window: " + reconnectTimeout
0820: + " seconds");
0821: reconnectTimeout *= 1000;
0822: ServerClientHandshakeManager clientHandshakeManager = new ServerClientHandshakeManager(
0823: TCLogging.getLogger(ServerClientHandshakeManager.class),
0824: channelManager,
0825: transactionManager,
0826: sequenceValidator,
0827: clientStateManager,
0828: lockManager,
0829: stageManager
0830: .getStage(
0831: ServerConfigurationContext.RESPOND_TO_LOCK_REQUEST_STAGE)
0832: .getSink(), objectStore, new TCTimerImpl(
0833: "Reconnect timer", true), reconnectTimeout,
0834: persistent, consoleLogger);
0835:
0836: boolean networkedHA = configSetupManager.haConfig()
0837: .isNetworkedActivePassive();
0838: if (networkedHA) {
0839: logger.info("L2 Networked HA Enabled ");
0840: l2Coordinator = new L2HACoordinator(consoleLogger, this ,
0841: stageManager, persistor.getClusterStateStore(),
0842: objectManager, transactionManager, gtxm,
0843: channelManager, configSetupManager.haConfig());
0844: l2Coordinator.getStateManager()
0845: .registerForStateChangeEvents(l2State);
0846: } else {
0847: l2State.setState(StateManager.ACTIVE_COORDINATOR);
0848: l2Coordinator = new L2HADisabledCooridinator();
0849: }
0850:
0851: context = new ServerConfigurationContextImpl(stageManager,
0852: objectManager, objectStore, lockManager,
0853: channelManager, clientStateManager, transactionManager,
0854: txnObjectManager, clientHandshakeManager, channelStats,
0855: l2Coordinator,
0856: new CommitTransactionMessageToTransactionBatchReader(
0857: gtxm));
0858:
0859: stageManager.startAll(context);
0860:
0861: DSOGlobalServerStats serverStats = new DSOGlobalServerStatsImpl(
0862: globalObjectFlushCounter, globalObjectFaultCounter,
0863: globalTxnCounter, objMgrStats);
0864:
0865: // XXX: yucky casts
0866: managementContext = new ServerManagementContext(
0867: transactionManager, (ObjectManagerMBean) objectManager,
0868: (LockManagerMBean) lockManager,
0869: (DSOChannelManagerMBean) channelManager, serverStats,
0870: channelStats, instanceMonitor, appEvents);
0871:
0872: if (l2Properties.getBoolean("beanshell.enabled"))
0873: startBeanShell(l2Properties.getInt("beanshell.port"));
0874:
0875: lockStatsManager.start(channelManager, lockManager,
0876: respondToLockRequestStage.getSink());
0877:
0878: if (networkedHA) {
0879: final Node this Node = makeThisNode();
0880: final Node[] allNodes = makeAllNodes();
0881: l2Coordinator.start(this Node, allNodes);
0882: } else {
0883: // In non-network enabled HA, Only active server reached here.
0884: startActiveMode();
0885: }
0886: }
0887:
0888: public boolean isBlocking() {
0889: return startupLock != null && startupLock.isBlocking();
0890:
0891: }
0892:
0893: private Node[] makeAllNodes() {
0894: String[] l2s = configSetupManager.allCurrentlyKnownServers();
0895: Node[] rv = new Node[l2s.length];
0896: for (int i = 0; i < l2s.length; i++) {
0897: NewL2DSOConfig l2;
0898: try {
0899: l2 = configSetupManager.dsoL2ConfigFor(l2s[i]);
0900: } catch (ConfigurationSetupException e) {
0901: throw new RuntimeException(
0902: "Error getting l2 config for: " + l2s[i], e);
0903: }
0904: rv[i] = makeNode(l2);
0905: }
0906: return rv;
0907: }
0908:
0909: private static Node makeNode(NewL2DSOConfig l2) {
0910: // NOTE: until we resolve Tribes stepping on TCComm's port
0911: // we'll use TCComm.port + 1 in Tribes
0912: int dsoPort = l2.listenPort().getInt();
0913: if (dsoPort == 0) {
0914: return new Node(l2.host().getString(), dsoPort);
0915: } else {
0916: return new Node(l2.host().getString(), l2.l2GroupPort()
0917: .getInt());
0918: }
0919: }
0920:
0921: private Node makeThisNode() {
0922: NewL2DSOConfig l2 = configSetupManager.dsoL2Config();
0923: return makeNode(l2);
0924: }
0925:
0926: public boolean startActiveMode() throws IOException {
0927: transactionManager.goToActiveMode();
0928: Set existingConnections = Collections
0929: .unmodifiableSet(connectionIdFactory
0930: .loadConnectionIDs());
0931: context.getClientHandshakeManager().setStarting(
0932: existingConnections);
0933: l1Listener.start(existingConnections);
0934: consoleLogger
0935: .info("Terracotta Server has started up as ACTIVE node on port "
0936: + l1Listener.getBindPort()
0937: + " successfully, and is now ready for work.");
0938: return true;
0939: }
0940:
0941: public boolean stopActiveMode() throws TCTimeoutException {
0942: // TODO:: Make this not take timeout and force stop
0943: consoleLogger.info("Stopping ACTIVE Terracotta Server on port "
0944: + l1Listener.getBindPort() + ".");
0945: l1Listener.stop(10000);
0946: l1Listener.getChannelManager().closeAllChannels();
0947: return true;
0948: }
0949:
0950: public void startBeanShell(int port) {
0951: try {
0952: Interpreter i = new Interpreter();
0953: i.set("dsoServer", this );
0954: i.set("objectManager", objectManager);
0955: i.set("txnObjectManager", txnObjectManager);
0956: i.set("portnum", port);
0957: i.eval("setAccessibility(true)"); // turn off access restrictions
0958: i.eval("server(portnum)");
0959: consoleLogger.info("Bean shell is started on port " + port);
0960: } catch (EvalError e) {
0961: e.printStackTrace();
0962: }
0963: }
0964:
0965: public int getListenPort() {
0966: return this .l1Listener.getBindPort();
0967: }
0968:
0969: public synchronized void stop() {
0970: try {
0971: if (lockManager != null)
0972: lockManager.stop();
0973: } catch (InterruptedException e) {
0974: logger.error(e);
0975: }
0976:
0977: getStageManager().stopAll();
0978:
0979: if (l1Listener != null) {
0980: try {
0981: l1Listener.stop(5000);
0982: } catch (TCTimeoutException e) {
0983: logger.warn("timeout trying to stop listener: "
0984: + e.getMessage());
0985: }
0986: }
0987:
0988: if ((communicationsManager != null)) {
0989: communicationsManager.shutdown();
0990: }
0991:
0992: if (objectManager != null) {
0993: try {
0994: objectManager.stop();
0995: } catch (Throwable e) {
0996: logger.error(e);
0997: }
0998: }
0999:
1000: clientStateManager.stop();
1001:
1002: try {
1003: objectStore.shutdown();
1004: } catch (Throwable e) {
1005: logger.warn(e);
1006: }
1007:
1008: try {
1009: persistor.close();
1010: } catch (DBException e) {
1011: logger.warn(e);
1012: }
1013:
1014: if (sampledCounterManager != null) {
1015: try {
1016: sampledCounterManager.shutdown();
1017: } catch (Exception e) {
1018: logger.error(e);
1019: }
1020: }
1021:
1022: try {
1023: stopJMXServer();
1024: } catch (Throwable t) {
1025: logger.error("Error shutting down jmx server", t);
1026: }
1027:
1028: basicStop();
1029: }
1030:
1031: public void quickStop() {
1032: try {
1033: stopJMXServer();
1034: } catch (Throwable t) {
1035: logger.error("Error shutting down jmx server", t);
1036: }
1037:
1038: // XXX: not calling basicStop() here, it creates a race condition with the Sleepycat's own writer lock (see
1039: // LKC-3239) Provided we ever fix graceful server shutdown, we'll want to uncommnet this at that time and/or get rid
1040: // of this method completely
1041:
1042: // basicStop();
1043: }
1044:
1045: private void basicStop() {
1046: if (startupLock != null) {
1047: startupLock.release();
1048: }
1049: }
1050:
1051: public ConnectionIDFactory getConnectionIdFactory() {
1052: return connectionIdFactory;
1053: }
1054:
1055: public ManagedObjectStore getManagedObjectStore() {
1056: return objectStore;
1057: }
1058:
1059: public ServerConfigurationContext getContext() {
1060: return context;
1061: }
1062:
1063: public ServerManagementContext getManagementContext() {
1064: return managementContext;
1065: }
1066:
1067: public MBeanServer getMBeanServer() {
1068: return l2Management.getMBeanServer();
1069: }
1070:
1071: private void startJMXServer() throws Exception {
1072: l2Management = new L2Management(tcServerInfoMBean,
1073: lockStatisticsMBean, configSetupManager, this );
1074:
1075: /*
1076: * Some tests use this if they run with jdk1.4 and start multiple in-process DistributedObjectServers. When we no
1077: * longer support 1.4, this can be removed. See com.tctest.LockManagerSystemTest.
1078: */
1079: if (!Boolean
1080: .getBoolean("org.terracotta.server.disableJmxConnector")) {
1081: l2Management.start();
1082: }
1083: }
1084:
1085: private void stopJMXServer() throws Exception {
1086: try {
1087: if (l2Management != null) {
1088: l2Management.stop();
1089: }
1090: } finally {
1091: l2Management = null;
1092: }
1093: }
1094: }
|