SocketParams() {
    TCProperties props = TCPropertiesImpl.getProperties().getPropertiesFor(PREFIX);

    this.recvBuffer = props.getInt(RECV_BUFFER, -1);
    this.sendBuffer = props.getInt(SEND_BUFFER, -1);
    this.keepAlive = props.getBoolean(KEEP_ALIVE);
    this.tcpNoDelay = props.getBoolean(TCP_NO_DELAY);
  }
Beispiel #2
0
 public CacheConfigImpl(TCProperties cacheManagerProperties) {
   leastCount = cacheManagerProperties.getInt("leastCount");
   percentageToEvict = cacheManagerProperties.getInt("percentageToEvict");
   sleepInterval = cacheManagerProperties.getLong("sleepInterval");
   criticalThreshold = cacheManagerProperties.getInt("criticalThreshold");
   threshold = cacheManagerProperties.getInt("threshold");
   monitorOldGenOnly = cacheManagerProperties.getBoolean("monitorOldGenOnly");
   loggingEnabled = cacheManagerProperties.getBoolean("logging.enabled");
   criticalObjectThreshold = cacheManagerProperties.getInt("criticalObjectThreshold");
 }
  public synchronized void start() {
    validateSecurityConfig();

    final TCProperties tcProperties = TCPropertiesImpl.getProperties();
    final int maxSize = tcProperties.getInt(TCPropertiesConsts.L1_SEDA_STAGE_SINK_CAPACITY);

    final SessionManager sessionManager =
        new SessionManagerImpl(
            new SessionManagerImpl.SequenceFactory() {
              @Override
              public Sequence newSequence() {
                return new SimpleSequence();
              }
            });

    this.threadGroup.addCallbackOnExitDefaultHandler(
        new CallbackOnExitHandler() {
          @Override
          public void callbackOnExit(CallbackOnExitState state) {
            cluster.fireNodeError();
          }
        });
    this.dumpHandler.registerForDump(new CallbackDumpAdapter(this.communicationStageManager));

    final ReconnectConfig l1ReconnectConfig = getReconnectPropertiesFromServer();

    final boolean useOOOLayer = l1ReconnectConfig.getReconnectEnabled();
    final NetworkStackHarnessFactory networkStackHarnessFactory =
        getNetworkStackHarnessFactory(useOOOLayer, l1ReconnectConfig);

    this.counterManager = new CounterManagerImpl();
    final MessageMonitor mm = MessageMonitorImpl.createMonitor(tcProperties, DSO_LOGGER);
    final TCMessageRouter messageRouter = new TCMessageRouterImpl();

    this.communicationsManager =
        this.clientBuilder.createCommunicationsManager(
            mm,
            messageRouter,
            networkStackHarnessFactory,
            new NullConnectionPolicy(),
            this.connectionComponents.createConnectionInfoConfigItemByGroup().length,
            new HealthCheckerConfigClientImpl(
                tcProperties.getPropertiesFor(TCPropertiesConsts.L1_L2_HEALTH_CHECK_CATEGORY),
                "DSO Client"),
            getMessageTypeClassMapping(),
            ReconnectionRejectedHandlerL1.SINGLETON,
            securityManager,
            productId);

    DSO_LOGGER.debug("Created CommunicationsManager.");

    final ConnectionInfoConfig[] connectionInfoItems =
        this.connectionComponents.createConnectionInfoConfigItemByGroup();
    final ConnectionInfo[] connectionInfo = connectionInfoItems[0].getConnectionInfos();
    final String serverHost = connectionInfo[0].getHostname();
    final int serverPort = connectionInfo[0].getPort();

    clusterEventsStage =
        this.communicationStageManager.createStage(
            ClientConfigurationContext.CLUSTER_EVENTS_STAGE,
            ClusterInternalEventsContext.class,
            new ClusterInternalEventsHandler<ClusterInternalEventsContext>(cluster),
            1,
            maxSize);

    final int socketConnectTimeout =
        tcProperties.getInt(TCPropertiesConsts.L1_SOCKET_CONNECT_TIMEOUT);

    if (socketConnectTimeout < 0) {
      throw new IllegalArgumentException("invalid socket time value: " + socketConnectTimeout);
    }
    this.channel =
        this.clientBuilder.createClientMessageChannel(
            this.communicationsManager,
            this.connectionComponents,
            sessionManager,
            MAX_CONNECT_TRIES,
            socketConnectTimeout,
            this);

    final ClientIDLoggerProvider cidLoggerProvider = new ClientIDLoggerProvider(this.channel);
    this.communicationStageManager.setLoggerProvider(cidLoggerProvider);

    DSO_LOGGER.debug("Created channel.");

    this.clientEntityManager =
        this.clientBuilder.createClientEntityManager(this.channel, this.communicationStageManager);
    RequestReceiveHandler receivingHandler = new RequestReceiveHandler(this.clientEntityManager);
    Stage<VoltronEntityResponse> entityResponseStage =
        this.communicationStageManager.createStage(
            ClientConfigurationContext.VOLTRON_ENTITY_RESPONSE_STAGE,
            VoltronEntityResponse.class,
            receivingHandler,
            1,
            maxSize);

    Stage<Void> serverMessageStage =
        this.communicationStageManager.createStage(
            ClientConfigurationContext.SERVER_ENTITY_MESSAGE_STAGE,
            Void.class,
            new ServerMessageReceiveHandler<Void>(channel),
            1,
            maxSize);

    TerracottaOperatorEventLogging.setNodeNameProvider(new ClientNameProvider(this.cluster));

    final SampledRateCounterConfig sampledRateCounterConfig =
        new SampledRateCounterConfig(1, 300, true);
    this.counterManager.createCounter(sampledRateCounterConfig);
    this.counterManager.createCounter(sampledRateCounterConfig);

    // for SRA L1 Tx count
    final SampledCounterConfig sampledCounterConfig = new SampledCounterConfig(1, 300, true, 0L);
    this.counterManager.createCounter(sampledCounterConfig);

    this.threadGroup.addCallbackOnExitDefaultHandler(
        new CallbackDumpAdapter(this.clientEntityManager));
    this.dumpHandler.registerForDump(new CallbackDumpAdapter(this.clientEntityManager));

    final long timeOut =
        TCPropertiesImpl.getProperties().getLong(TCPropertiesConsts.LOGGING_LONG_GC_THRESHOLD);
    final LongGCLogger gcLogger = this.clientBuilder.createLongGCLogger(timeOut);
    this.tcMemManager.registerForMemoryEvents(gcLogger);
    // CDV-1181 warn if using CMS
    this.tcMemManager.checkGarbageCollectors();

    this.threadIDManager = new ThreadIDManagerImpl(this.threadIDMap);
    // Setup the lock manager
    this.lockManager =
        this.clientBuilder.createLockManager(
            this.channel,
            new ClientIDLogger(this.channel, TCLogging.getLogger(ClientLockManager.class)),
            sessionManager,
            this.channel.getLockRequestMessageFactory(),
            this.threadIDManager,
            new ClientLockManagerConfigImpl(
                tcProperties.getPropertiesFor(TCPropertiesConsts.L1_LOCK_MANAGER_CATEGORY)),
            this.taskRunner);
    final CallbackDumpAdapter lockDumpAdapter = new CallbackDumpAdapter(this.lockManager);
    this.threadGroup.addCallbackOnExitDefaultHandler(lockDumpAdapter);
    this.dumpHandler.registerForDump(lockDumpAdapter);

    // Create the SEDA stages
    final Stage<Void> lockResponse =
        this.communicationStageManager.createStage(
            ClientConfigurationContext.LOCK_RESPONSE_STAGE,
            Void.class,
            new LockResponseHandler<Void>(sessionManager),
            1,
            maxSize);

    final Stage<HydrateContext> hydrateStage =
        this.communicationStageManager.createStage(
            ClientConfigurationContext.HYDRATE_MESSAGE_STAGE,
            HydrateContext.class,
            new HydrateHandler(),
            1,
            maxSize);

    // By design this stage needs to be single threaded. If it wasn't then cluster membership
    // messages could get
    // processed before the client handshake ack, and this client would get a faulty view of the
    // cluster at best, or
    // more likely an AssertionError
    final Stage<PauseContext> pauseStage =
        this.communicationStageManager.createStage(
            ClientConfigurationContext.CLIENT_COORDINATION_STAGE,
            PauseContext.class,
            new ClientCoordinationHandler<PauseContext>(),
            1,
            maxSize);
    final Sink<PauseContext> pauseSink = pauseStage.getSink();

    final Stage<Void> clusterMembershipEventStage =
        this.communicationStageManager.createStage(
            ClientConfigurationContext.CLUSTER_MEMBERSHIP_EVENT_STAGE,
            Void.class,
            new ClusterMembershipEventsHandler<Void>(cluster),
            1,
            maxSize);
    final List<ClientHandshakeCallback> clientHandshakeCallbacks =
        new ArrayList<ClientHandshakeCallback>();
    clientHandshakeCallbacks.add(this.lockManager);
    clientHandshakeCallbacks.add(this.clientEntityManager);
    final ProductInfo pInfo = ProductInfo.getInstance();
    this.clientHandshakeManager =
        this.clientBuilder.createClientHandshakeManager(
            new ClientIDLogger(this.channel, TCLogging.getLogger(ClientHandshakeManagerImpl.class)),
            this.channel.getClientHandshakeMessageFactory(),
            pauseSink,
            sessionManager,
            cluster,
            this.uuid,
            this.name,
            pInfo.version(),
            Collections.unmodifiableCollection(clientHandshakeCallbacks));

    ClientChannelEventController.connectChannelEventListener(
        channel, pauseSink, clientHandshakeManager);

    this.shutdownManager = new ClientShutdownManager(this, connectionComponents);

    final ClientConfigurationContext cc =
        new ClientConfigurationContext(
            this.communicationStageManager,
            this.lockManager,
            this.clientEntityManager,
            this.clientHandshakeManager);
    // DO NOT create any stages after this call
    this.communicationStageManager.startAll(cc, Collections.<PostInit>emptyList());

    initChannelMessageRouter(
        messageRouter,
        hydrateStage.getSink(),
        lockResponse.getSink(),
        pauseSink,
        clusterMembershipEventStage.getSink(),
        entityResponseStage.getSink(),
        serverMessageStage.getSink());
    new Thread(
            threadGroup,
            new Runnable() {
              public void run() {
                while (!clientStopped.isSet()) {
                  try {
                    openChannel(serverHost, serverPort);
                    waitForHandshake();
                    connectionMade();
                    break;
                  } catch (InterruptedException ie) {
                    // We are in the process of letting the thread terminate so we don't handle this
                    // in a special way.
                  }
                }
                //  don't reset interrupted, thread is done
              }
            },
            "Connection Establisher - " + uuid)
        .start();
  }
  @SuppressWarnings("resource")
  public void setLogDirectory(File theDirectory, int processType) {
    Assert.assertNotNull(theDirectory);

    if (theDirectory.getName().trim().equalsIgnoreCase("stdout:")
        || theDirectory.getName().trim().equalsIgnoreCase("stderr:")) {
      if (currentLoggingDirectory != null
          && currentLoggingDirectory.getName().trim().equalsIgnoreCase(theDirectory.getName())) {
        // Nothing to do; great!
        return;
      }

      delegateFileAppender.setDelegate(new NullAppender());
      consoleAppender.setLayout(new PatternLayout(CONSOLE_LOGGING_ONLY_PATTERN));

      // Logger.addAppender() doesn't double-add, so this is safe
      Logger.getRootLogger().addAppender(consoleAppender);

      if (buffering) {
        BufferingAppender realBufferingAppender =
            (BufferingAppender) delegateBufferingAppender.setDelegate(new NullAppender());
        realBufferingAppender.stopAndSendContentsTo(consoleAppender);
        realBufferingAppender.close();
        buffering = false;
      }

      boolean stdout = theDirectory.getName().trim().equalsIgnoreCase("stdout:");
      getConsoleLogger()
          .info(
              "All logging information now output to standard "
                  + (stdout ? "output" : "error")
                  + ".");

      return;
    }

    synchronized (TCLoggingLog4J.class) {
      if (currentLoggingDirectory != null) {
        try {
          if (theDirectory.getCanonicalPath().equals(currentLoggingDirectory.getCanonicalPath())) {
            return;
          }
        } catch (IOException ioe) {
          // oh, well -- what can we do? we'll continue on.
        }
      }
    }

    try {
      FileUtils.forceMkdir(theDirectory);
    } catch (IOException ioe) {
      reportLoggingError(
          "We can't create the directory '"
              + theDirectory.getAbsolutePath()
              + "' that you specified for your logs.",
          ioe);
      return;
    }

    if (!theDirectory.canWrite()) {
      // formatting
      reportLoggingError(
          "The log directory, '" + theDirectory.getAbsolutePath() + "', can't be written to.",
          null);
      return;
    }

    FileLock thisDirectoryLock = null;

    if (!lockingDisabled) {
      File lockFile = new File(theDirectory, LOCK_FILE_NAME);

      try {
        lockFile.createNewFile();
        Assert.eval(lockFile.exists());
        FileChannel channel = new RandomAccessFile(lockFile, "rw").getChannel();
        thisDirectoryLock = channel.tryLock();

        if (thisDirectoryLock == null) {
          reportLoggingError(
              "The log directory, '"
                  + theDirectory.getAbsolutePath()
                  + "', is already in use by another "
                  + "Terracotta process. Logging will proceed to the console only.",
              null);
          return;
        }

      } catch (OverlappingFileLockException ofle) {
        // This VM already holds the lock; no problem
      } catch (IOException ioe) {
        reportLoggingError(
            "We can't lock the file '"
                + lockFile.getAbsolutePath()
                + "', to make sure that only one "
                + "Terracotta process is using this directory for logging. This may be a permission "
                + "issue, or some unexpected error. Logging will proceed to the console only.",
            ioe);
        return;
      }
    }

    RollingFileAppender newFileAppender;

    String logFileName;

    switch (processType) {
      case PROCESS_TYPE_L1:
        logFileName = TERRACOTTA_L1_LOG_FILE_NAME;
        break;

      case PROCESS_TYPE_L2:
        logFileName = TERRACOTTA_L2_LOG_FILE_NAME;
        break;

      case PROCESS_TYPE_GENERIC:
        logFileName = TERRACOTTA_GENERIC_LOG_FILE_NAME;
        break;

      default:
        throw Assert.failure("Unknown process type: " + processType);
    }

    String logFilePath = new File(theDirectory, logFileName).getAbsolutePath();

    synchronized (TCLoggingLog4J.class) {
      try {
        TCProperties props =
            TCPropertiesImpl.getProperties().getPropertiesFor(TCPropertiesConsts.LOGGING_CATEGORY);
        newFileAppender =
            new TCRollingFileAppender(new PatternLayout(FILE_AND_JMX_PATTERN), logFilePath, true);
        newFileAppender.setName("file appender");
        int maxLogFileSize = props.getInt(MAX_LOG_FILE_SIZE_PROPERTY, DEFAULT_MAX_LOG_FILE_SIZE);
        newFileAppender.setMaxFileSize(maxLogFileSize + "MB");
        newFileAppender.setMaxBackupIndex(props.getInt(MAX_BACKUPS_PROPERTY, DEFAULT_MAX_BACKUPS));

        // This makes us start with a new file each time.
        newFileAppender.rollOver();

        // Note: order of operations is very important here. We start the new appender before we
        // close and remove the
        // old one so that you don't drop any log records.
        Appender oldFileAppender = delegateFileAppender.setDelegate(newFileAppender);

        if (oldFileAppender != null) {
          oldFileAppender.close();
        }

        if (buffering) {
          BufferingAppender realBufferingAppender =
              (BufferingAppender) delegateBufferingAppender.setDelegate(new NullAppender());
          realBufferingAppender.stopAndSendContentsTo(delegateFileAppender);
          realBufferingAppender.close();
          buffering = false;
        }

        currentLoggingDirectory = theDirectory;

        if (currentLoggingDirectoryFileLock != null) currentLoggingDirectoryFileLock.release();
        currentLoggingDirectoryFileLock = thisDirectoryLock;
      } catch (IOException ioe) {
        reportLoggingError(
            "We were unable to switch the logging system to log to '" + logFilePath + "'.", ioe);
      }
    }

    getConsoleLogger().info("Log file: '" + logFilePath + "'.");
    writeSystemProperties();
  }