示例#1
0
  /**
   * Construct a media driver with the given context.
   *
   * @param context for the media driver parameters
   */
  private MediaDriver(final Context context) {
    this.ctx = context;

    ensureDirectoryIsRecreated(context);

    validateSufficientSocketBufferLengths(context);

    context
        .toConductorFromReceiverCommandQueue(new OneToOneConcurrentArrayQueue<>(CMD_QUEUE_CAPACITY))
        .toConductorFromSenderCommandQueue(new OneToOneConcurrentArrayQueue<>(CMD_QUEUE_CAPACITY))
        .receiverCommandQueue(new OneToOneConcurrentArrayQueue<>(CMD_QUEUE_CAPACITY))
        .senderCommandQueue(new OneToOneConcurrentArrayQueue<>(CMD_QUEUE_CAPACITY))
        .conclude();

    final Receiver receiver = new Receiver(context);
    final Sender sender = new Sender(context);
    final DriverConductor conductor = new DriverConductor(context);

    context.receiverProxy().receiver(receiver);
    context.senderProxy().sender(sender);
    context.fromReceiverDriverConductorProxy().driverConductor(conductor);
    context.fromSenderDriverConductorProxy().driverConductor(conductor);
    context.toDriverCommands().consumerHeartbeatTime(context.epochClock().time());

    final AtomicCounter errorCounter = context.systemCounters().errors();
    final ErrorHandler errorHandler = context.errorHandler();

    switch (context.threadingMode) {
      case SHARED:
        runners =
            Collections.singletonList(
                new AgentRunner(
                    context.sharedIdleStrategy,
                    errorHandler,
                    errorCounter,
                    new CompositeAgent(sender, receiver, conductor)));
        break;

      case SHARED_NETWORK:
        runners =
            Arrays.asList(
                new AgentRunner(
                    context.sharedNetworkIdleStrategy,
                    errorHandler,
                    errorCounter,
                    new CompositeAgent(sender, receiver)),
                new AgentRunner(
                    context.conductorIdleStrategy, errorHandler, errorCounter, conductor));
        break;

      default:
      case DEDICATED:
        runners =
            Arrays.asList(
                new AgentRunner(context.senderIdleStrategy, errorHandler, errorCounter, sender),
                new AgentRunner(context.receiverIdleStrategy, errorHandler, errorCounter, receiver),
                new AgentRunner(
                    context.conductorIdleStrategy, errorHandler, errorCounter, conductor));
    }
  }
示例#2
0
  private void ensureDirectoryIsRecreated(final Context ctx) {
    final File aeronDir = new File(ctx.dirName());
    Consumer<String> logProgress = (message) -> {};

    if (aeronDir.exists()) {
      if (ctx.warnIfDirectoriesExist()) {
        System.err.println("WARNING: " + aeronDir + " already exists.");
        logProgress = System.err::println;
      }

      if (ctx.dirsDeleteOnStart()) {
        ctx.deleteAeronDirectory();
      } else {
        final boolean driverActive = ctx.isDriverActive(ctx.driverTimeoutMs(), logProgress);

        if (driverActive) {
          throw new ActiveDriverException("active driver detected");
        }

        ctx.deleteAeronDirectory();
      }
    }

    final BiConsumer<String, String> callback =
        (path, name) -> {
          if (ctx.warnIfDirectoriesExist()) {
            System.err.println("WARNING: " + name + " directory already exists: " + path);
          }
        };

    IoUtil.ensureDirectoryIsRecreated(aeronDir, "aeron", callback);
  }
示例#3
0
  /** Shutdown the media driver by stopping all threads and freeing resources. */
  public void close() {
    try {
      runners.forEach(AgentRunner::close);

      freeSocketsForReuseOnWindows();
      ctx.close();
    } catch (final Exception ex) {
      LangUtil.rethrowUnchecked(ex);
    }
  }
示例#4
0
  private static void validateSufficientSocketBufferLengths(final Context ctx) {
    try (final DatagramChannel probe = DatagramChannel.open()) {
      final int defaultSoSndBuf = probe.getOption(StandardSocketOptions.SO_SNDBUF);

      probe.setOption(StandardSocketOptions.SO_SNDBUF, Integer.MAX_VALUE);
      final int maxSoSndBuf = probe.getOption(StandardSocketOptions.SO_SNDBUF);

      if (maxSoSndBuf < Configuration.SOCKET_SNDBUF_LENGTH) {
        System.err.format(
            "WARNING: Could not get desired SO_SNDBUF: attempted=%d, actual=%d\n",
            Configuration.SOCKET_SNDBUF_LENGTH, maxSoSndBuf);
      }

      probe.setOption(StandardSocketOptions.SO_RCVBUF, Integer.MAX_VALUE);
      final int maxSoRcvBuf = probe.getOption(StandardSocketOptions.SO_RCVBUF);

      if (maxSoRcvBuf < Configuration.SOCKET_RCVBUF_LENGTH) {
        System.err.format(
            "WARNING: Could not get desired SO_RCVBUF: attempted=%d, actual=%d\n",
            Configuration.SOCKET_RCVBUF_LENGTH, maxSoRcvBuf);
      }

      final int soSndBuf =
          (0 == Configuration.SOCKET_SNDBUF_LENGTH)
              ? defaultSoSndBuf
              : Configuration.SOCKET_SNDBUF_LENGTH;

      if (ctx.mtuLength() > soSndBuf) {
        throw new ConfigurationException(
            String.format(
                "MTU greater than socket SO_SNDBUF: mtuLength=%d, SO_SNDBUF=%d",
                ctx.mtuLength(), soSndBuf));
      }
    } catch (final IOException ex) {
      throw new RuntimeException(String.format("probe socket: %s", ex.toString()), ex);
    }
  }
示例#5
0
 private void freeSocketsForReuseOnWindows() {
   ctx.receiverTransportPoller().selectNowWithoutProcessing();
   ctx.senderTransportPoller().selectNowWithoutProcessing();
 }
示例#6
0
 /**
  * Used to access the configured dirName for this MediaDriver Context typically used after the
  * {@link #launchEmbedded()} method is used.
  *
  * @return the context dirName
  */
 public String contextDirName() {
   return ctx.dirName();
 }
示例#7
0
 /**
  * Launch an isolated MediaDriver embedded in the current process with a provided configuration
  * context and a generated dirName (overwrites configured dirName) that can be retrieved by
  * calling contextDirName.
  *
  * @param ctx containing the configuration options.
  * @return the newly started MediaDriver.
  */
 public static MediaDriver launchEmbedded(final Context ctx) {
   ctx.dirName(CommonContext.generateRandomDirName());
   return launch(ctx);
 }
示例#8
0
 /**
  * Used to access the configured aeronDirectoryName for this MediaDriver, typically used after the
  * {@link #launchEmbedded()} method is used.
  *
  * @return the context aeronDirectoryName
  */
 public String aeronDirectoryName() {
   return ctx.aeronDirectoryName();
 }
示例#9
0
 /**
  * Launch an isolated MediaDriver embedded in the current process with a provided configuration
  * context and a generated aeronDirectoryName (overwrites configured aeronDirectoryName) that can
  * be retrieved by calling aeronDirectoryName.
  *
  * @param context containing the configuration options.
  * @return the newly started MediaDriver.
  */
 public static MediaDriver launchEmbedded(final Context context) {
   context.aeronDirectoryName(CommonContext.generateRandomDirName());
   return launch(context);
 }