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

io.aeron.driver.MediaDriver Maven / Gradle / Ivy

There is a newer version: 1.46.2
Show newest version
/*
 * Copyright 2014-2023 Real Logic Limited.
 *
 * 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
 *
 * https://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.
 */
package io.aeron.driver;

import io.aeron.Aeron;
import io.aeron.CncFileDescriptor;
import io.aeron.CommonContext;
import io.aeron.driver.buffer.FileStoreLogFactory;
import io.aeron.driver.buffer.LogFactory;
import io.aeron.driver.exceptions.ActiveDriverException;
import io.aeron.driver.media.*;
import io.aeron.driver.reports.LossReport;
import io.aeron.driver.status.DutyCycleStallTracker;
import io.aeron.driver.status.SystemCounters;
import io.aeron.exceptions.AeronException;
import io.aeron.exceptions.ConcurrentConcludeException;
import io.aeron.logbuffer.BufferClaim;
import io.aeron.logbuffer.LogBufferDescriptor;
import io.aeron.version.Versioned;
import org.agrona.*;
import org.agrona.concurrent.*;
import org.agrona.concurrent.broadcast.BroadcastTransmitter;
import org.agrona.concurrent.errors.DistinctErrorLog;
import org.agrona.concurrent.ringbuffer.ManyToOneRingBuffer;
import org.agrona.concurrent.ringbuffer.RingBuffer;
import org.agrona.concurrent.status.*;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.StandardSocketOptions;
import java.nio.ByteOrder;
import java.nio.MappedByteBuffer;
import java.nio.channels.DatagramChannel;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.function.Consumer;

import static io.aeron.CncFileDescriptor.*;
import static io.aeron.driver.Configuration.*;
import static io.aeron.driver.reports.LossReportUtil.mapLossReport;
import static io.aeron.driver.status.SystemCounterDescriptor.CONTROLLABLE_IDLE_STRATEGY;
import static io.aeron.driver.status.SystemCounterDescriptor.*;
import static io.aeron.logbuffer.LogBufferDescriptor.TERM_MAX_LENGTH;
import static java.nio.charset.StandardCharsets.US_ASCII;
import static java.util.concurrent.atomic.AtomicIntegerFieldUpdater.newUpdater;
import static org.agrona.BitUtil.SIZE_OF_LONG;
import static org.agrona.IoUtil.mapNewFile;
import static org.agrona.SystemUtil.loadPropertiesFiles;
import static org.agrona.concurrent.status.CountersReader.METADATA_LENGTH;

/**
 * Main class for JVM-based media driver
 * 

* Usage: * * $ java -jar aeron-driver.jar * $ java -Doption=value -jar aeron-driver.jar * * * @see Configuration */ @Versioned public final class MediaDriver implements AutoCloseable { private boolean wasHighResTimerEnabled; private final AgentRunner sharedRunner; private final AgentRunner sharedNetworkRunner; private final AgentRunner conductorRunner; private final AgentRunner receiverRunner; private final AgentRunner senderRunner; private final AgentInvoker sharedInvoker; private final Context ctx; /** * Main method for launching the process. * * @param args passed to the process. */ @SuppressWarnings("try") public static void main(final String[] args) { loadPropertiesFiles(args); final ShutdownSignalBarrier barrier = new ShutdownSignalBarrier(); final MediaDriver.Context ctx = new MediaDriver.Context().terminationHook(barrier::signal); try (MediaDriver ignore = MediaDriver.launch(ctx)) { barrier.await(); System.out.println("Shutdown Driver..."); } } /** * Construct a media driver with the given ctx. * * @param ctx for the media driver parameters */ private MediaDriver(final Context ctx) { ctx.concludeAeronDirectory(); ensureDirectoryIsRecreated(ctx); validateSocketBufferLengths(ctx); try { ctx.conclude(); this.ctx = ctx; final DriverConductor conductor = new DriverConductor(ctx); final Receiver receiver = new Receiver(ctx); final Sender sender = new Sender(ctx); ctx.receiverProxy().receiver(receiver); ctx.senderProxy().sender(sender); ctx.driverConductorProxy().driverConductor(conductor); final AtomicCounter errorCounter = ctx.systemCounters().get(ERRORS); final ErrorHandler errorHandler = ctx.errorHandler(); switch (ctx.threadingMode()) { case INVOKER: sharedInvoker = new AgentInvoker( errorHandler, errorCounter, new CompositeAgent(sender, receiver, conductor)); sharedRunner = null; sharedNetworkRunner = null; conductorRunner = null; receiverRunner = null; senderRunner = null; break; case SHARED: sharedRunner = new AgentRunner( ctx.sharedIdleStrategy(), errorHandler, errorCounter, new CompositeAgent(sender, receiver, conductor)); sharedNetworkRunner = null; conductorRunner = null; receiverRunner = null; senderRunner = null; sharedInvoker = null; break; case SHARED_NETWORK: sharedNetworkRunner = new AgentRunner( ctx.sharedNetworkIdleStrategy(), errorHandler, errorCounter, new CompositeAgent(sender, receiver)); conductorRunner = new AgentRunner( ctx.conductorIdleStrategy(), errorHandler, errorCounter, conductor); sharedRunner = null; receiverRunner = null; senderRunner = null; sharedInvoker = null; break; default: case DEDICATED: senderRunner = new AgentRunner(ctx.senderIdleStrategy(), errorHandler, errorCounter, sender); receiverRunner = new AgentRunner(ctx.receiverIdleStrategy(), errorHandler, errorCounter, receiver); conductorRunner = new AgentRunner( ctx.conductorIdleStrategy(), errorHandler, errorCounter, conductor); sharedNetworkRunner = null; sharedRunner = null; sharedInvoker = null; break; } } catch (final ConcurrentConcludeException ex) { throw ex; } catch (final Exception ex) { CloseHelper.quietClose(ctx::close); throw ex; } } /** * Launch an isolated MediaDriver embedded in the current process with a generated aeronDirectoryName that can be * retrieved by calling aeronDirectoryName. *

* If the aeronDirectoryName is set as a system property to something different from * {@link CommonContext#AERON_DIR_PROP_DEFAULT} then this set value will be used. * * @return the newly started MediaDriver. */ public static MediaDriver launchEmbedded() { return launchEmbedded(new Context()); } /** * Launch an isolated MediaDriver embedded in the current process with a provided configuration ctx and a generated * aeronDirectoryName (overwrites configured {@link Context#aeronDirectoryName()}) that can be retrieved by calling * aeronDirectoryName. *

* If the aeronDirectoryName is set as a system property, or via context, to something different from * {@link CommonContext#AERON_DIR_PROP_DEFAULT} then this set value will be used. * * @param ctx containing the configuration options. * @return the newly started MediaDriver. */ public static MediaDriver launchEmbedded(final Context ctx) { if (CommonContext.AERON_DIR_PROP_DEFAULT.equals(ctx.aeronDirectoryName())) { ctx.aeronDirectoryName(CommonContext.generateRandomDirName()); } return launch(ctx); } /** * Launch a MediaDriver embedded in the current process with default configuration. * * @return the newly started MediaDriver. */ public static MediaDriver launch() { return launch(new Context()); } /** * Launch a MediaDriver embedded in the current process and provided a configuration ctx. * * @param ctx containing the configuration options. * @return the newly created MediaDriver. */ public static MediaDriver launch(final Context ctx) { final MediaDriver mediaDriver = new MediaDriver(ctx); if (ctx.useWindowsHighResTimer() && SystemUtil.isWindows()) { mediaDriver.wasHighResTimerEnabled = HighResolutionTimer.isEnabled(); if (!mediaDriver.wasHighResTimerEnabled) { HighResolutionTimer.enable(); } } if (null != mediaDriver.conductorRunner) { AgentRunner.startOnThread(mediaDriver.conductorRunner, ctx.conductorThreadFactory()); } if (null != mediaDriver.senderRunner) { AgentRunner.startOnThread(mediaDriver.senderRunner, ctx.senderThreadFactory()); } if (null != mediaDriver.receiverRunner) { AgentRunner.startOnThread(mediaDriver.receiverRunner, ctx.receiverThreadFactory()); } if (null != mediaDriver.sharedNetworkRunner) { AgentRunner.startOnThread(mediaDriver.sharedNetworkRunner, ctx.sharedNetworkThreadFactory()); } if (null != mediaDriver.sharedRunner) { AgentRunner.startOnThread(mediaDriver.sharedRunner, ctx.sharedThreadFactory()); } if (null != mediaDriver.sharedInvoker) { mediaDriver.sharedInvoker.start(); } return mediaDriver; } /** * Get the {@link MediaDriver.Context} that is used by this {@link MediaDriver}. * * @return the {@link MediaDriver.Context} that is used by this {@link MediaDriver}. */ public Context context() { return ctx; } /** * Get the {@link AgentInvoker} for the shared agents when running without threads. * * @return the {@link AgentInvoker} for the shared agents when running without threads. */ public AgentInvoker sharedAgentInvoker() { return sharedInvoker; } /** * Shutdown the media driver by stopping all threads and freeing resources. */ public void close() { try { CloseHelper.closeAll( sharedRunner, sharedNetworkRunner, receiverRunner, senderRunner, conductorRunner, sharedInvoker); } finally { if (ctx.useWindowsHighResTimer() && SystemUtil.isWindows() && !wasHighResTimerEnabled) { HighResolutionTimer.disable(); } } } /** * 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(); } private static void ensureDirectoryIsRecreated(final Context ctx) { if (ctx.aeronDirectory().isDirectory()) { if (ctx.warnIfDirectoryExists()) { System.err.println("WARNING: " + ctx.aeronDirectory() + " exists"); } if (!ctx.dirDeleteOnStart()) { final Consumer logger = ctx.warnIfDirectoryExists() ? System.err::println : (s) -> {}; final MappedByteBuffer cncByteBuffer = ctx.mapExistingCncFile(logger); try { if (CommonContext.isDriverActive(ctx.driverTimeoutMs(), logger, cncByteBuffer)) { throw new ActiveDriverException("active driver detected"); } reportExistingErrors(ctx, cncByteBuffer); } finally { BufferUtil.free(cncByteBuffer); } } ctx.deleteDirectory(); } IoUtil.ensureDirectoryExists(ctx.aeronDirectory(), "aeron"); } private static void reportExistingErrors(final Context ctx, final MappedByteBuffer cncByteBuffer) { try { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final int observations = ctx.saveErrorLog(new PrintStream(baos, false, "US-ASCII"), cncByteBuffer); if (observations > 0) { final StringBuilder builder = new StringBuilder(ctx.aeronDirectoryName()); IoUtil.removeTrailingSlashes(builder); final SimpleDateFormat dateFormat = new SimpleDateFormat("-yyyy-MM-dd-HH-mm-ss-SSSZ"); builder.append(dateFormat.format(new Date())).append("-error.log"); final String errorLogFilename = builder.toString(); System.err.println("WARNING: Existing errors saved to: " + errorLogFilename); try (FileOutputStream out = new FileOutputStream(errorLogFilename)) { baos.writeTo(out); } } } catch (final Exception ex) { LangUtil.rethrowUnchecked(ex); } } /** * Context for the {@link MediaDriver} that can be used to provide overrides for {@link Configuration}. *

* Note: Do not reuse instances of this {@link Context} across different {@link MediaDriver}s. *

* The context will be owned by {@link DriverConductor} after a successful * {@link MediaDriver#launch(Context)} and closed via {@link MediaDriver#close()}. */ public static final class Context extends CommonContext { private static final AtomicIntegerFieldUpdater IS_CLOSED_UPDATER = newUpdater( MediaDriver.Context.class, "isClosed"); private volatile int isClosed; private boolean printConfigurationOnStart = Configuration.printConfigurationOnStart(); private boolean useWindowsHighResTimer = Configuration.useWindowsHighResTimer(); private boolean warnIfDirectoryExists = Configuration.warnIfDirExists(); private boolean dirDeleteOnStart = Configuration.dirDeleteOnStart(); private boolean dirDeleteOnShutdown = Configuration.dirDeleteOnShutdown(); private boolean termBufferSparseFile = Configuration.termBufferSparseFile(); private boolean performStorageChecks = Configuration.performStorageChecks(); private boolean spiesSimulateConnection = Configuration.spiesSimulateConnection(); private boolean reliableStream = Configuration.reliableStream(); private boolean tetherSubscriptions = Configuration.tetherSubscriptions(); private boolean rejoinStream = Configuration.rejoinStream(); private long lowStorageWarningThreshold = Configuration.lowStorageWarningThreshold(); private long timerIntervalNs = Configuration.timerIntervalNs(); private long clientLivenessTimeoutNs = Configuration.clientLivenessTimeoutNs(); private long imageLivenessTimeoutNs = Configuration.imageLivenessTimeoutNs(); private long publicationUnblockTimeoutNs = Configuration.publicationUnblockTimeoutNs(); private long publicationConnectionTimeoutNs = Configuration.publicationConnectionTimeoutNs(); private long publicationLingerTimeoutNs = Configuration.publicationLingerTimeoutNs(); private long untetheredWindowLimitTimeoutNs = Configuration.untetheredWindowLimitTimeoutNs(); private long untetheredRestingTimeoutNs = Configuration.untetheredRestingTimeoutNs(); private long statusMessageTimeoutNs = Configuration.statusMessageTimeoutNs(); private long counterFreeToReuseTimeoutNs = Configuration.counterFreeToReuseTimeoutNs(); private long retransmitUnicastDelayNs = Configuration.retransmitUnicastDelayNs(); private long retransmitUnicastLingerNs = Configuration.retransmitUnicastLingerNs(); private long nakUnicastDelayNs = Configuration.nakUnicastDelayNs(); private long nakMulticastMaxBackoffNs = Configuration.nakMulticastMaxBackoffNs(); private long flowControlReceiverTimeoutNs = Configuration.flowControlReceiverTimeoutNs(); private long reResolutionCheckIntervalNs = Configuration.reResolutionCheckIntervalNs(); private long conductorCycleThresholdNs = Configuration.conductorCycleThresholdNs(); private long senderCycleThresholdNs = Configuration.senderCycleThresholdNs(); private long receiverCycleThresholdNs = Configuration.receiverCycleThresholdNs(); private long nameResolverThresholdNs = Configuration.nameResolverThresholdNs(); private int conductorBufferLength = Configuration.conductorBufferLength(); private int toClientsBufferLength = Configuration.toClientsBufferLength(); private int counterValuesBufferLength = Configuration.counterValuesBufferLength(); private int errorBufferLength = Configuration.errorBufferLength(); private int nakMulticastGroupSize = Configuration.nakMulticastGroupSize(); private int publicationTermBufferLength = Configuration.termBufferLength(); private int ipcTermBufferLength = Configuration.ipcTermBufferLength(); private int publicationTermWindowLength = Configuration.publicationTermWindowLength(); private int ipcPublicationTermWindowLength = Configuration.ipcPublicationTermWindowLength(); private int initialWindowLength = Configuration.initialWindowLength(); private int socketSndbufLength = Configuration.socketSndbufLength(); private int socketRcvbufLength = Configuration.socketRcvbufLength(); private int socketMulticastTtl = Configuration.socketMulticastTtl(); private int mtuLength = Configuration.mtuLength(); private int ipcMtuLength = Configuration.ipcMtuLength(); private int filePageSize = Configuration.filePageSize(); private int publicationReservedSessionIdLow = Configuration.publicationReservedSessionIdLow(); private int publicationReservedSessionIdHigh = Configuration.publicationReservedSessionIdHigh(); private int lossReportBufferLength = Configuration.lossReportBufferLength(); private int sendToStatusMessagePollRatio = Configuration.sendToStatusMessagePollRatio(); private int resourceFreeLimit = Configuration.resourceFreeLimit(); private Long receiverGroupTag = Configuration.groupTag(); private long flowControlGroupTag = Configuration.flowControlGroupTag(); private int flowControlGroupMinSize = Configuration.flowControlGroupMinSize(); private InferableBoolean receiverGroupConsideration = Configuration.receiverGroupConsideration(); private String resolverName = Configuration.resolverName(); private String resolverInterface = Configuration.resolverInterface(); private String resolverBootstrapNeighbor = Configuration.resolverBootstrapNeighbor(); private String senderWildcardPortRange = Configuration.senderWildcardPortRange(); private String receiverWildcardPortRange = Configuration.receiverWildcardPortRange(); private EpochClock epochClock; private NanoClock nanoClock; private CachedEpochClock cachedEpochClock; private CachedNanoClock cachedNanoClock; private CachedNanoClock senderCachedNanoClock; private CachedNanoClock receiverCachedNanoClock; private ThreadingMode threadingMode; private ThreadFactory conductorThreadFactory; private ThreadFactory senderThreadFactory; private ThreadFactory receiverThreadFactory; private ThreadFactory sharedThreadFactory; private ThreadFactory sharedNetworkThreadFactory; private IdleStrategy conductorIdleStrategy; private IdleStrategy senderIdleStrategy; private IdleStrategy receiverIdleStrategy; private IdleStrategy sharedNetworkIdleStrategy; private IdleStrategy sharedIdleStrategy; private SendChannelEndpointSupplier sendChannelEndpointSupplier; private ReceiveChannelEndpointSupplier receiveChannelEndpointSupplier; private ReceiveChannelEndpointThreadLocals receiveChannelEndpointThreadLocals; private MutableDirectBuffer tempBuffer; private FlowControlSupplier unicastFlowControlSupplier; private FlowControlSupplier multicastFlowControlSupplier; private byte[] applicationSpecificFeedback; private CongestionControlSupplier congestionControlSupplier; private FeedbackDelayGenerator unicastFeedbackDelayGenerator; private FeedbackDelayGenerator multicastFeedbackDelayGenerator; private FeedbackDelayGenerator retransmitUnicastDelayGenerator; private FeedbackDelayGenerator retransmitUnicastLingerGenerator; private TerminationValidator terminationValidator; private Runnable terminationHook; private NameResolver nameResolver; private DistinctErrorLog errorLog; private ErrorHandler errorHandler; private boolean useConcurrentCountersManager; private CountersManager countersManager; private SystemCounters systemCounters; private LossReport lossReport; private LogFactory logFactory; private DataTransportPoller dataTransportPoller; private ControlTransportPoller controlTransportPoller; private ManyToOneConcurrentArrayQueue driverCommandQueue; private OneToOneConcurrentArrayQueue receiverCommandQueue; private OneToOneConcurrentArrayQueue senderCommandQueue; private ReceiverProxy receiverProxy; private SenderProxy senderProxy; private DriverConductorProxy driverConductorProxy; private ClientProxy clientProxy; private RingBuffer toDriverCommands; private MappedByteBuffer lossReportBuffer; private MappedByteBuffer cncByteBuffer; private UnsafeBuffer cncMetaDataBuffer; private int osDefaultSocketRcvbufLength = Aeron.NULL_VALUE; private int osMaxSocketRcvbufLength = Aeron.NULL_VALUE; private int osDefaultSocketSndbufLength = Aeron.NULL_VALUE; private int osMaxSocketSndbufLength = Aeron.NULL_VALUE; private EpochNanoClock channelReceiveTimestampClock; private EpochNanoClock channelSendTimestampClock; private DutyCycleTracker conductorDutyCycleTracker; private DutyCycleTracker senderDutyCycleTracker; private DutyCycleTracker receiverDutyCycleTracker; private DutyCycleTracker nameResolverTimeTracker; private PortManager senderPortManager; private PortManager receiverPortManager; /** * Perform a shallow copy of the object. * * @return a shallow copy of the object. */ public Context clone() { return (Context)super.clone(); } /** * Free up resources but don't delete files in case they are required for debugging unless * {@link #dirDeleteOnShutdown()} is set. */ public void close() { if (IS_CLOSED_UPDATER.compareAndSet(this, 0, 1)) { CloseHelper.close(errorHandler, logFactory); if (null != systemCounters) { final AtomicCounter errorCounter = systemCounters.get(ERRORS); errorCounter.disconnectCountersManager(); errorCounter.close(); } if (errorHandler instanceof AutoCloseable) { CloseHelper.quietClose((AutoCloseable)errorHandler); } BufferUtil.free(lossReportBuffer); this.lossReportBuffer = null; BufferUtil.free(cncByteBuffer); this.cncByteBuffer = null; if (dirDeleteOnShutdown) { this.deleteDirectory(); } super.close(); } } /** * {@inheritDoc} */ public Context conclude() { super.conclude(); try { concludeNullProperties(); resolveOsSocketBufLengths(); validateMtuLength(mtuLength); validateMtuLength(ipcMtuLength); validatePageSize(filePageSize); validateValueRange( conductorBufferLength, CONDUCTOR_BUFFER_LENGTH_DEFAULT, Integer.MAX_VALUE, "conductorBufferLength"); validateValueRange( toClientsBufferLength, TO_CLIENTS_BUFFER_LENGTH_DEFAULT, Integer.MAX_VALUE, "toClientsBufferLength"); validateValueRange( counterValuesBufferLength, COUNTERS_VALUES_BUFFER_LENGTH_DEFAULT, COUNTERS_VALUES_BUFFER_LENGTH_MAX, "counterValuesBufferLength"); validateValueRange( errorBufferLength, ERROR_BUFFER_LENGTH_DEFAULT, Integer.MAX_VALUE, "errorBufferLength"); validateValueRange( publicationTermWindowLength, 0, TERM_MAX_LENGTH, "publicationTermWindowLength"); validateValueRange( ipcPublicationTermWindowLength, 0, TERM_MAX_LENGTH, "ipcPublicationTermWindowLength"); validateSessionIdRange(publicationReservedSessionIdLow, publicationReservedSessionIdHigh); LogBufferDescriptor.checkTermLength(publicationTermBufferLength); LogBufferDescriptor.checkTermLength(ipcTermBufferLength); validateInitialWindowLength(initialWindowLength, mtuLength); validateUnblockTimeout(publicationUnblockTimeoutNs, clientLivenessTimeoutNs, timerIntervalNs); validateUntetheredTimeouts(untetheredWindowLimitTimeoutNs, untetheredRestingTimeoutNs, timerIntervalNs); final long cncFileLength = BitUtil.align( (long)END_OF_METADATA_OFFSET + conductorBufferLength + toClientsBufferLength + countersMetadataBufferLength(counterValuesBufferLength) + counterValuesBufferLength + errorBufferLength, filePageSize); validateValueRange(cncFileLength, 0, Integer.MAX_VALUE, "CnC file length"); cncByteBuffer = mapNewFile(cncFile(), cncFileLength); cncMetaDataBuffer = CncFileDescriptor.createMetaDataBuffer(cncByteBuffer); CncFileDescriptor.fillMetaData( cncMetaDataBuffer, conductorBufferLength, toClientsBufferLength, Configuration.countersMetadataBufferLength(counterValuesBufferLength), counterValuesBufferLength, clientLivenessTimeoutNs, errorBufferLength, epochClock.time(), SystemUtil.getPid()); concludeCounters(); concludeDependantProperties(); concludeIdleStrategies(); toDriverCommands.nextCorrelationId(); toDriverCommands.consumerHeartbeatTime(epochClock.time()); CncFileDescriptor.signalCncReady(cncMetaDataBuffer); } catch (final Exception ex) { LangUtil.rethrowUnchecked(ex); } if (printConfigurationOnStart) { System.out.println(this); } return this; } /** * Delete the directory used by the {@link MediaDriver} which delegates to * {@link CommonContext#deleteAeronDirectory()}. */ public void deleteDirectory() { if (null != aeronDirectory()) { super.deleteAeronDirectory(); } } /** * {@inheritDoc} */ public Context aeronDirectoryName(final String dirName) { super.aeronDirectoryName(dirName); return this; } /** * {@inheritDoc} */ public Context driverTimeoutMs(final long value) { super.driverTimeoutMs(value); return this; } /** * {@inheritDoc} */ public Context countersMetaDataBuffer(final UnsafeBuffer countersMetaDataBuffer) { super.countersMetaDataBuffer(countersMetaDataBuffer); return this; } /** * {@inheritDoc} */ public Context countersValuesBuffer(final UnsafeBuffer countersValuesBuffer) { super.countersValuesBuffer(countersValuesBuffer); return this; } /** * Should the driver print its configuration on start to {@link System#out} at the end of {@link #conclude()}. * * @return true if the configuration should be printed on start. * @see Configuration#PRINT_CONFIGURATION_ON_START_PROP_NAME */ public boolean printConfigurationOnStart() { return printConfigurationOnStart; } /** * Should the driver print its configuration on start to {@link System#out} at the end of {@link #conclude()}. * * @param printConfigurationOnStart if the configuration should be printed on start. * @return this for a fluent API. * @see Configuration#PRINT_CONFIGURATION_ON_START_PROP_NAME */ public Context printConfigurationOnStart(final boolean printConfigurationOnStart) { this.printConfigurationOnStart = printConfigurationOnStart; return this; } /** * Should an attempt be made to use the high resolution timers for waiting on Windows. * * @param useWindowsHighResTimers Should an attempt be made to use the high-res timers for waiting on Windows. * @return this for a fluent API. * @see Configuration#USE_WINDOWS_HIGH_RES_TIMER_PROP_NAME */ public Context useWindowsHighResTimer(final boolean useWindowsHighResTimers) { this.useWindowsHighResTimer = useWindowsHighResTimers; return this; } /** * Should an attempt be made to use the high resolution timers for waiting on Windows. * * @return true if an attempt be made to use the high resolution timers for waiting on Windows. * @see Configuration#USE_WINDOWS_HIGH_RES_TIMER_PROP_NAME */ public boolean useWindowsHighResTimer() { return useWindowsHighResTimer; } /** * Should a warning be issued if the {@link #aeronDirectoryName()} exists? * * @return should a warning be issued if the {@link #aeronDirectoryName()} exists? * @see Configuration#DIR_WARN_IF_EXISTS_PROP_NAME */ public boolean warnIfDirectoryExists() { return warnIfDirectoryExists; } /** * Should a warning be issued if the {@link #aeronDirectoryName()} exists? * * @param warnIfDirectoryExists warn if the {@link #aeronDirectoryName()} exists? * @return this for a fluent API. * @see Configuration#DIR_WARN_IF_EXISTS_PROP_NAME */ public Context warnIfDirectoryExists(final boolean warnIfDirectoryExists) { this.warnIfDirectoryExists = warnIfDirectoryExists; return this; } /** * Will the driver attempt to immediately delete {@link #aeronDirectoryName()} on startup. * WARNING: {@link #aeronDirectoryName()} will be recreated regardless, unless set to false * and an active Media Driver is detected. * * @return true when directory will be recreated without checks, otherwise false. * @see Configuration#DIR_DELETE_ON_START_PROP_NAME */ public boolean dirDeleteOnStart() { return dirDeleteOnStart; } /** * Should the driver attempt to immediately delete {@link #aeronDirectoryName()} on startup. * WARNING: {@link #aeronDirectoryName()} will be recreated regardless, unless set to false * and an active Media Driver is detected. * * @param dirDeleteOnStart Attempt deletion without checks. * @return this for a fluent API. * @see Configuration#DIR_DELETE_ON_START_PROP_NAME */ public Context dirDeleteOnStart(final boolean dirDeleteOnStart) { this.dirDeleteOnStart = dirDeleteOnStart; return this; } /** * Will the driver attempt to delete {@link #aeronDirectoryName()} on shutdown. * * @return true when directory will be deleted, otherwise false. * @see Configuration#DIR_DELETE_ON_SHUTDOWN_PROP_NAME */ public boolean dirDeleteOnShutdown() { return dirDeleteOnShutdown; } /** * Should the driver attempt to delete {@link #aeronDirectoryName()} on shutdown. * * @param dirDeleteOnShutdown Attempt deletion. * @return this for a fluent API. * @see Configuration#DIR_DELETE_ON_SHUTDOWN_PROP_NAME */ public Context dirDeleteOnShutdown(final boolean dirDeleteOnShutdown) { this.dirDeleteOnShutdown = dirDeleteOnShutdown; return this; } /** * Should the term buffers be created with sparse files? * * @return should the term buffers be created with sparse files? * @see Configuration#TERM_BUFFER_SPARSE_FILE_PROP_NAME */ public boolean termBufferSparseFile() { return termBufferSparseFile; } /** * Should the term buffer be created with sparse files? * * @param termBufferSparseFile should the term buffers be created with sparse files? * @return this for a fluent API. * @see Configuration#TERM_BUFFER_SPARSE_FILE_PROP_NAME */ public Context termBufferSparseFile(final boolean termBufferSparseFile) { this.termBufferSparseFile = termBufferSparseFile; return this; } /** * Length of the {@link RingBuffer} for sending commands to the driver conductor from clients. * * @return length of the {@link RingBuffer} for sending commands to the driver conductor from clients. * @see Configuration#CONDUCTOR_BUFFER_LENGTH_PROP_NAME */ public int conductorBufferLength() { return conductorBufferLength; } /** * Length of the {@link RingBuffer} for sending commands to the driver conductor from clients. * * @param length of the {@link RingBuffer} for sending commands to the driver conductor from clients. * @return this for a fluent API. * @see Configuration#CONDUCTOR_BUFFER_LENGTH_PROP_NAME */ public Context conductorBufferLength(final int length) { conductorBufferLength = length; return this; } /** * Length of the {@link BroadcastTransmitter} buffer for sending events to the clients. * * @return length of the {@link BroadcastTransmitter} buffer for sending events to the clients. * @see Configuration#TO_CLIENTS_BUFFER_LENGTH_PROP_NAME */ public int toClientsBufferLength() { return toClientsBufferLength; } /** * Length of the {@link BroadcastTransmitter} buffer for sending events to the clients. * * @param length of the {@link BroadcastTransmitter} buffer for sending events to the clients. * @return this for a fluent API. * @see Configuration#TO_CLIENTS_BUFFER_LENGTH_PROP_NAME */ public Context toClientsBufferLength(final int length) { toClientsBufferLength = length; return this; } /** * Length of the buffer for storing values by the {@link CountersManager}. * * @return length of the buffer for storing values by the {@link CountersManager}. * @see Configuration#COUNTERS_VALUES_BUFFER_LENGTH_PROP_NAME */ public int counterValuesBufferLength() { return counterValuesBufferLength; } /** * Length of the buffer for storing values by the {@link CountersManager}. * * @param length of the buffer for storing values by the {@link CountersManager}. * @return this for a fluent API. * @see Configuration#COUNTERS_VALUES_BUFFER_LENGTH_PROP_NAME */ public Context counterValuesBufferLength(final int length) { counterValuesBufferLength = length; return this; } /** * Length of the {@link DistinctErrorLog} buffer for recording exceptions. * * @return length of the {@link DistinctErrorLog} buffer for recording exceptions. * @see Configuration#ERROR_BUFFER_LENGTH_PROP_NAME */ public int errorBufferLength() { return errorBufferLength; } /** * Length of the {@link DistinctErrorLog} buffer for recording exceptions. * * @param length of the {@link DistinctErrorLog} buffer for recording exceptions. * @return this for a fluent API. * @see Configuration#ERROR_BUFFER_LENGTH_PROP_NAME */ public Context errorBufferLength(final int length) { errorBufferLength = length; return this; } /** * Should the driver perform storage checks when allocating files. * * @return true if the driver should perform storage checks when allocating files. * @see Configuration#PERFORM_STORAGE_CHECKS_PROP_NAME */ public boolean performStorageChecks() { return performStorageChecks; } /** * Should the driver perform storage checks when allocating files. * * @param performStorageChecks true if the driver should perform storage checks when allocating files. * @return this for a fluent API. * @see Configuration#PERFORM_STORAGE_CHECKS_PROP_NAME */ public Context performStorageChecks(final boolean performStorageChecks) { this.performStorageChecks = performStorageChecks; return this; } /** * Get the threshold in bytes below which storage warnings are issued. * * @return the threshold below which storage warnings are issued. * @see Configuration#LOW_FILE_STORE_WARNING_THRESHOLD_PROP_NAME */ public long lowStorageWarningThreshold() { return lowStorageWarningThreshold; } /** * Get the threshold in bytes below which storage warnings are issued. * * @param lowStorageWarningThreshold to be set in bytes. * @return this for a fluent API. * @see Configuration#LOW_FILE_STORE_WARNING_THRESHOLD_PROP_NAME */ public Context lowStorageWarningThreshold(final long lowStorageWarningThreshold) { this.lowStorageWarningThreshold = lowStorageWarningThreshold; return this; } /** * The length in bytes of the loss report buffer. * * @return the length in bytes of the loss report buffer. * @see Configuration#LOSS_REPORT_BUFFER_LENGTH_PROP_NAME */ public int lossReportBufferLength() { return lossReportBufferLength; } /** * The length in bytes of the loss report buffer. * * @param length of the buffer to be used for the loss report. * @return this for a fluent API. * @see Configuration#LOSS_REPORT_BUFFER_LENGTH_PROP_NAME */ public Context lossReportBufferLength(final int length) { lossReportBufferLength = length; return this; } /** * Page size for alignment of all files. * * @return page size for alignment of all files. * @see Configuration#FILE_PAGE_SIZE_PROP_NAME */ public int filePageSize() { return filePageSize; } /** * Page size for alignment of all files. * * @param filePageSize for alignment of file sizes. * @return this for a fluent API. * @see Configuration#FILE_PAGE_SIZE_PROP_NAME */ public Context filePageSize(final int filePageSize) { this.filePageSize = filePageSize; return this; } /** * Interval in nanoseconds between checks for timers and timeouts. * * @return nanoseconds between checks for timers and timeouts. * @see Configuration#TIMER_INTERVAL_PROP_NAME */ public long timerIntervalNs() { return timerIntervalNs; } /** * Interval in nanoseconds between checks for timers and timeouts. * * @param timerIntervalNs nanoseconds between checks for timers and timeouts. * @return this for a fluent API. * @see Configuration#TIMER_INTERVAL_PROP_NAME */ public Context timerIntervalNs(final long timerIntervalNs) { this.timerIntervalNs = timerIntervalNs; return this; } /** * Time in nanoseconds an Image will be kept alive for its subscribers to consume it once disconnected. * * @return nanoseconds that an Image will be kept alive for its subscribers to consume it. * @see Configuration#IMAGE_LIVENESS_TIMEOUT_PROP_NAME */ public long imageLivenessTimeoutNs() { return imageLivenessTimeoutNs; } /** * Time in nanoseconds an Image will be kept alive after for its subscribers to consume it once disconnected. * * @param timeout for keeping an image alive for its subscribers to consume it. * @return this for a fluent API. * @see Configuration#IMAGE_LIVENESS_TIMEOUT_PROP_NAME */ public Context imageLivenessTimeoutNs(final long timeout) { this.imageLivenessTimeoutNs = timeout; return this; } /** * Time in nanoseconds a publication will linger once it is drained to recover potential tail loss. * * @return nanoseconds that a publication will linger once it is drained. * @see Configuration#PUBLICATION_LINGER_PROP_NAME */ public long publicationLingerTimeoutNs() { return publicationLingerTimeoutNs; } /** * Time in nanoseconds a publication will linger once it is drained to recover potential tail loss. * * @param timeoutNs for keeping a publication once it is drained. * @return this for a fluent API. * @see Configuration#PUBLICATION_LINGER_PROP_NAME */ public Context publicationLingerTimeoutNs(final long timeoutNs) { this.publicationLingerTimeoutNs = timeoutNs; return this; } /** * The timeout for when an untethered subscription that is outside the window will participate * in local flow control. * * @return timeout that an untethered subscription outside the window limit will participate in flow control. * @see Configuration#UNTETHERED_WINDOW_LIMIT_TIMEOUT_PROP_NAME */ public long untetheredWindowLimitTimeoutNs() { return untetheredWindowLimitTimeoutNs; } /** * The timeout for when an untethered subscription that is outside the window will participate * in local flow control. * * @param timeoutNs that an untethered subscription outside the window limit will participate in flow control. * @return this for a fluent API. * @see Configuration#UNTETHERED_WINDOW_LIMIT_TIMEOUT_PROP_NAME */ public Context untetheredWindowLimitTimeoutNs(final long timeoutNs) { this.untetheredWindowLimitTimeoutNs = timeoutNs; return this; } /** * Timeout for when an untethered subscription is resting after not being able to keep up before it is allowed * to rejoin a stream. * * @return timeout that an untethered subscription is resting before being allowed to rejoin a stream. * @see Configuration#UNTETHERED_RESTING_TIMEOUT_PROP_NAME */ public long untetheredRestingTimeoutNs() { return untetheredRestingTimeoutNs; } /** * Timeout for when an untethered subscription is resting after not being able to keep up before it is allowed * to rejoin a stream. * * @param timeoutNs that an untethered subscription is resting before being allowed to rejoin a stream. * @return this for a fluent API. * @see Configuration#UNTETHERED_RESTING_TIMEOUT_PROP_NAME */ public Context untetheredRestingTimeoutNs(final long timeoutNs) { this.untetheredRestingTimeoutNs = timeoutNs; return this; } /** * The delay before retransmitting after a NAK. * * @return delay before retransmitting after a NAK. * @see Configuration#RETRANSMIT_UNICAST_DELAY_PROP_NAME */ public long retransmitUnicastDelayNs() { return retransmitUnicastDelayNs; } /** * The delay before retransmitting after a NAK. * * @param retransmitUnicastDelayNs delay before retransmitting after a NAK. * @return this for a fluent API. * @see Configuration#RETRANSMIT_UNICAST_DELAY_PROP_NAME */ public Context retransmitUnicastDelayNs(final long retransmitUnicastDelayNs) { this.retransmitUnicastDelayNs = retransmitUnicastDelayNs; return this; } /** * How long to linger after delay on a NAK before responding to another NAK. * * @return how long to linger after delay on a NAK before responding to another NAK. * @see Configuration#RETRANSMIT_UNICAST_LINGER_PROP_NAME */ public long retransmitUnicastLingerNs() { return retransmitUnicastLingerNs; } /** * How long to linger after delay on a NAK before responding to another NAK. * * @param retransmitUnicastLingerNs how long to linger after delay on a NAK before responding to another NAK. * @return this for a fluent API. * @see Configuration#RETRANSMIT_UNICAST_LINGER_PROP_NAME */ public Context retransmitUnicastLingerNs(final long retransmitUnicastLingerNs) { this.retransmitUnicastLingerNs = retransmitUnicastLingerNs; return this; } /** * The delay before retransmission after an NAK on unicast. * * @return delay before retransmitting after a NAK. * @see Configuration#NAK_UNICAST_DELAY_PROP_NAME */ public long nakUnicastDelayNs() { return nakUnicastDelayNs; } /** * The delay before retransmission after an NAK on unicast. * * @param nakUnicastDelayNs delay before retransmission after an NAK on unicast. * @return this for a fluent API. * @see Configuration#NAK_UNICAST_DELAY_PROP_NAME */ public Context nakUnicastDelayNs(final long nakUnicastDelayNs) { this.nakUnicastDelayNs = nakUnicastDelayNs; return this; } /** * The maximum time to backoff before sending a NAK on multicast. * * @return maximum time to backoff before sending a NAK on multicast. * @see Configuration#NAK_MULTICAST_MAX_BACKOFF_PROP_NAME */ public long nakMulticastMaxBackoffNs() { return nakMulticastMaxBackoffNs; } /** * The maximum time to backoff before sending a NAK on multicast. * * @param nakMulticastMaxBackoffNs maximum time to backoff before sending a NAK on multicast. * @return this for a fluent API. * @see Configuration#NAK_MULTICAST_MAX_BACKOFF_PROP_NAME */ public Context nakMulticastMaxBackoffNs(final long nakMulticastMaxBackoffNs) { this.nakMulticastMaxBackoffNs = nakMulticastMaxBackoffNs; return this; } /** * Estimate of the multicast receiver group size on a stream. * * @return estimate of the multicast receiver group size on a stream. * @see Configuration#NAK_MULTICAST_GROUP_SIZE_PROP_NAME */ public int nakMulticastGroupSize() { return nakMulticastGroupSize; } /** * Estimate of the multicast receiver group size on a stream. * * @param nakMulticastGroupSize estimate of the multicast receiver group size on a stream. * @return this for a fluent API. * @see Configuration#NAK_MULTICAST_GROUP_SIZE_PROP_NAME */ public Context nakMulticastGroupSize(final int nakMulticastGroupSize) { this.nakMulticastGroupSize = nakMulticastGroupSize; return this; } /** * Time in nanoseconds after which a client is considered dead if a keep alive is not received. * * @return time in nanoseconds after which a client is considered dead if a keep alive is not received. * @see Configuration#CLIENT_LIVENESS_TIMEOUT_PROP_NAME */ public long clientLivenessTimeoutNs() { return CommonContext.checkDebugTimeout(clientLivenessTimeoutNs, TimeUnit.NANOSECONDS); } /** * Time in nanoseconds after which a client is considered dead if a keep alive is not received. * * @param timeoutNs in nanoseconds after which a client is considered dead if a keep alive is not received. * @return this for a fluent API. * @see Configuration#CLIENT_LIVENESS_TIMEOUT_PROP_NAME */ public Context clientLivenessTimeoutNs(final long timeoutNs) { this.clientLivenessTimeoutNs = timeoutNs; return this; } /** * Time in nanoseconds after which a status message will be sent if data is flowing slowly. * * @return time in nanoseconds after which a status message will be sent if data is flowing slowly. * @see Configuration#STATUS_MESSAGE_TIMEOUT_PROP_NAME */ public long statusMessageTimeoutNs() { return statusMessageTimeoutNs; } /** * Time in nanoseconds after which a status message will be sent if data is flowing slowly. * * @param statusMessageTimeoutNs after which a status message will be sent if data is flowing slowly. * @return this for a fluent API. * @see Configuration#STATUS_MESSAGE_TIMEOUT_PROP_NAME */ public Context statusMessageTimeoutNs(final long statusMessageTimeoutNs) { this.statusMessageTimeoutNs = statusMessageTimeoutNs; return this; } /** * Time in nanoseconds after which a freed counter may be reused. * * @return time in nanoseconds after which a freed counter may be reused. * @see Configuration#COUNTER_FREE_TO_REUSE_TIMEOUT_PROP_NAME */ public long counterFreeToReuseTimeoutNs() { return counterFreeToReuseTimeoutNs; } /** * Time in nanoseconds after which a freed counter may be reused. * * @param counterFreeToReuseTimeoutNs after which a freed counter may be reused. * @return this for a fluent API. * @see Configuration#COUNTER_FREE_TO_REUSE_TIMEOUT_PROP_NAME */ public Context counterFreeToReuseTimeoutNs(final long counterFreeToReuseTimeoutNs) { this.counterFreeToReuseTimeoutNs = counterFreeToReuseTimeoutNs; return this; } /** * Timeout in nanoseconds after which a publication will be unblocked if an offer is partially complete to allow * other publishers to make progress. *

* A publication can become blocked if the client crashes while publishing or if * {@link io.aeron.Publication#tryClaim(int, BufferClaim)} is used without following up by calling * {@link BufferClaim#commit()} or {@link BufferClaim#abort()}. * * @return timeout in nanoseconds after which a publication will be unblocked. * @see Configuration#PUBLICATION_UNBLOCK_TIMEOUT_PROP_NAME */ public long publicationUnblockTimeoutNs() { return publicationUnblockTimeoutNs; } /** * Timeout in nanoseconds after which a publication will be unblocked if an offer is partially complete to allow * other publishers to make progress. *

* A publication can become blocked if the client crashes while publishing or if * {@link io.aeron.Publication#tryClaim(int, BufferClaim)} is used without following up by calling * {@link BufferClaim#commit()} or {@link BufferClaim#abort()}. * * @param timeoutNs in nanoseconds after which a publication will be unblocked. * @return this for a fluent API. * @see Configuration#PUBLICATION_UNBLOCK_TIMEOUT_PROP_NAME */ public Context publicationUnblockTimeoutNs(final long timeoutNs) { this.publicationUnblockTimeoutNs = timeoutNs; return this; } /** * Timeout in nanoseconds after which a publication will be considered not connected if no status messages are * received. * * @return timeout in nanoseconds after which a publication is considered not connected. * @see Configuration#PUBLICATION_CONNECTION_TIMEOUT_PROP_NAME */ public long publicationConnectionTimeoutNs() { return publicationConnectionTimeoutNs; } /** * Timeout in nanoseconds after which a publication will be considered not connected if no status messages are * received. * * @param timeoutNs in nanoseconds after which a publication will be considered not connected. * @return this for a fluent API. * @see Configuration#PUBLICATION_CONNECTION_TIMEOUT_PROP_NAME */ public Context publicationConnectionTimeoutNs(final long timeoutNs) { this.publicationConnectionTimeoutNs = timeoutNs; return this; } /** * Does a spy subscription simulate a connection to a network publication. *

* If true then this will override the min group size of the min and tagged flow control strategies. * * @return true if a spy subscription should simulate a connection to a network publication. * @see Configuration#SPIES_SIMULATE_CONNECTION_PROP_NAME */ public boolean spiesSimulateConnection() { return spiesSimulateConnection; } /** * Does a spy subscription simulate a connection to a network publication. *

* If true then this will override the min group size of the min and tagged flow control strategies. * * @param spiesSimulateConnection true if a spy subscription simulates a connection to a network publication. * @return this for a fluent API. * @see Configuration#SPIES_SIMULATE_CONNECTION_PROP_NAME */ public Context spiesSimulateConnection(final boolean spiesSimulateConnection) { this.spiesSimulateConnection = spiesSimulateConnection; return this; } /** * Does a stream NAK when loss is detected, reliable=true, or gap fill, reliable=false. *

* The default can be overridden with a channel param. * * @return true if NAK on loss to be reliable otherwise false for gap fill. * @see Configuration#RELIABLE_STREAM_PROP_NAME * @see CommonContext#RELIABLE_STREAM_PARAM_NAME */ public boolean reliableStream() { return reliableStream; } /** * Does a stream NAK when loss is detected, reliable=true, or gap fill, reliable=false. *

* The default can be overridden with a channel param. * * @param reliableStream true if a stream should NAK on loss otherwise gap fill. * @return this for a fluent API. * @see Configuration#RELIABLE_STREAM_PROP_NAME * @see CommonContext#RELIABLE_STREAM_PARAM_NAME */ public Context reliableStream(final boolean reliableStream) { this.reliableStream = reliableStream; return this; } /** * Do subscriptions have a tether, so they participate in local flow control when more than one. *

* The default can be overridden with a channel param. * * @return true if subscriptions should have a tether for local flow control. * @see Configuration#TETHER_SUBSCRIPTIONS_PROP_NAME * @see CommonContext#TETHER_PARAM_NAME */ public boolean tetherSubscriptions() { return tetherSubscriptions; } /** * Do subscriptions have a tether so, they participate in local flow control when more than one. *

* The default can be overridden with a channel param. * * @param tetherSubscription true if subscriptions should have a tether for local flow control. * @return this for a fluent API. * @see Configuration#TETHER_SUBSCRIPTIONS_PROP_NAME * @see CommonContext#TETHER_PARAM_NAME */ public Context tetherSubscriptions(final boolean tetherSubscription) { this.tetherSubscriptions = tetherSubscription; return this; } /** * Should network subscriptions be considered part of a group even if using a unicast endpoint, should it be * considered an individual even if using a multicast endpoint, or should the use of a unicast/multicast * endpoint infer the usage. *

* The default can be overridden with a channel param. * * @return FORCE_TRUE if subscriptions should be considered a group member, FORCE_FALSE if not, or depends * on endpoint. * @see Configuration#GROUP_RECEIVER_CONSIDERATION_PROP_NAME * @see CommonContext#GROUP_PARAM_NAME */ public InferableBoolean receiverGroupConsideration() { return receiverGroupConsideration; } /** * Should network subscriptions be considered part of a group even if using a unicast endpoint, should it be * considered an individual even if using a multicast endpoint, or should the use of a unicast/multicast * endpoint infer the usage. *

* The default can be overridden with a channel param. * * @param receiverGroupConsideration true if subscriptions should be considered a group member, * false if not, or infer from endpoint. * @return this for a fluent API. * @see Configuration#GROUP_RECEIVER_CONSIDERATION_PROP_NAME * @see CommonContext#GROUP_PARAM_NAME */ public Context receiverGroupConsideration(final InferableBoolean receiverGroupConsideration) { this.receiverGroupConsideration = receiverGroupConsideration; return this; } /** * Does a subscription attempt to rejoin an unavailable stream after a cooldown or not. *

* The default can be overridden with a channel param. * * @return true if subscription will rejoin after cooldown or false if not. * @see Configuration#REJOIN_STREAM_PROP_NAME * @see CommonContext#REJOIN_PARAM_NAME */ public boolean rejoinStream() { return rejoinStream; } /** * Does a subscription attempt to rejoin an unavailable stream after a cooldown or not. *

* The default can be overridden with a channel param. * * @param rejoinStream true if subscription will rejoin after cooldown or false if not. * @return this for a fluent API. * @see Configuration#REJOIN_STREAM_PROP_NAME * @see CommonContext#REJOIN_PARAM_NAME */ public Context rejoinStream(final boolean rejoinStream) { this.rejoinStream = rejoinStream; return this; } /** * Default length for a term buffer on a network publication. * * @return default length for a term buffer on a network publication. * @see Configuration#TERM_BUFFER_LENGTH_PROP_NAME */ public int publicationTermBufferLength() { return publicationTermBufferLength; } /** * Default length for a term buffer on a network publication. *

* This can be overridden on publication by using channel URI params. * * @param termBufferLength default length for a term buffer on a network publication. * @return this for a fluent API. * @see Configuration#TERM_BUFFER_LENGTH_PROP_NAME */ public Context publicationTermBufferLength(final int termBufferLength) { this.publicationTermBufferLength = termBufferLength; return this; } /** * Default length for a term buffer on an IPC publication. * * @return default length for a term buffer on an IPC publication. * @see Configuration#IPC_TERM_BUFFER_LENGTH_PROP_NAME */ public int ipcTermBufferLength() { return ipcTermBufferLength; } /** * Default length for a term buffer on an IPC publication. *

* This can be overridden on publication by using channel URI params. * * @param termBufferLength default length for a term buffer on an IPC publication. * @return this for a fluent API. * @see Configuration#IPC_TERM_BUFFER_LENGTH_PROP_NAME */ public Context ipcTermBufferLength(final int termBufferLength) { this.ipcTermBufferLength = termBufferLength; return this; } /** * Default length for a term buffer window on a network publication. * * @return default length for a term buffer window on a network publication. * @see Configuration#PUBLICATION_TERM_WINDOW_LENGTH_PROP_NAME */ public int publicationTermWindowLength() { return publicationTermWindowLength; } /** * Default length for a term buffer window on a network publication. * * @param termWindowLength default length for a term buffer window on a network publication. * @return this for a fluent API. * @see Configuration#PUBLICATION_TERM_WINDOW_LENGTH_PROP_NAME */ public Context publicationTermWindowLength(final int termWindowLength) { this.publicationTermWindowLength = termWindowLength; return this; } /** * Default length for a term buffer window on an IPC publication. * * @return default length for a term buffer window on an IPC publication. * @see Configuration#IPC_PUBLICATION_TERM_WINDOW_LENGTH_PROP_NAME */ public int ipcPublicationTermWindowLength() { return ipcPublicationTermWindowLength; } /** * Default length for a term buffer window on an IPC publication. * * @param termWindowLength default length for a term buffer window on an IPC publication. * @return this for a fluent API. * @see Configuration#IPC_PUBLICATION_TERM_WINDOW_LENGTH_PROP_NAME */ public Context ipcPublicationTermWindowLength(final int termWindowLength) { this.ipcPublicationTermWindowLength = termWindowLength; return this; } /** * The initial window for in flight data on a connection which must be less than * {@link Configuration#SOCKET_RCVBUF_LENGTH_PROP_NAME}. This needs to be configured for throughput respecting * BDP. * * @return The initial window for in flight data on a connection * @see Configuration#INITIAL_WINDOW_LENGTH_PROP_NAME */ public int initialWindowLength() { return initialWindowLength; } /** * The initial window for in flight data on a connection which must be less than * {@link Configuration#SOCKET_RCVBUF_LENGTH_PROP_NAME}. This needs to be configured for throughput respecting * BDP. * * @param initialWindowLength The initial window for in flight data on a connection * @return this for a fluent API. * @see Configuration#INITIAL_WINDOW_LENGTH_PROP_NAME */ public Context initialWindowLength(final int initialWindowLength) { this.initialWindowLength = initialWindowLength; return this; } /** * The socket send buffer length which is the OS SO_SNDBUF. * * @return the socket send buffer length. * @see Configuration#SOCKET_SNDBUF_LENGTH_PROP_NAME */ public int socketSndbufLength() { return socketSndbufLength; } /** * The socket send buffer length which is the OS SO_SNDBUF. * * @param socketSndbufLength which is the OS SO_SNDBUF. * @return this for a fluent API. * @see Configuration#SOCKET_SNDBUF_LENGTH_PROP_NAME */ public Context socketSndbufLength(final int socketSndbufLength) { this.socketSndbufLength = socketSndbufLength; return this; } /** * The socket send buffer length which is the OS SO_RCVBUF. * * @return the socket send buffer length. * @see Configuration#SOCKET_RCVBUF_LENGTH_PROP_NAME */ public int socketRcvbufLength() { return socketRcvbufLength; } /** * The socket send buffer length which is the OS SO_RCVBUF. * * @param socketRcvbufLength which is the OS SO_RCVBUF. * @return this for a fluent API. * @see Configuration#SOCKET_RCVBUF_LENGTH_PROP_NAME */ public Context socketRcvbufLength(final int socketRcvbufLength) { this.socketRcvbufLength = socketRcvbufLength; return this; } /** * The TTL value to be used for multicast sockets. * * @return TTL value to be used for multicast sockets. * @see Configuration#SOCKET_MULTICAST_TTL_PROP_NAME */ public int socketMulticastTtl() { return socketMulticastTtl; } /** * TTL value to be used for multicast sockets. * * @param ttl value to be used for multicast sockets. * @return this for a fluent API. * @see Configuration#SOCKET_MULTICAST_TTL_PROP_NAME */ public Context socketMulticastTtl(final int ttl) { socketMulticastTtl = ttl; return this; } /** * MTU in bytes for datagrams sent to the network. Messages larger than this are fragmented. *

* Larger MTUs reduce system call overhead at the expense of possible increase in loss which * will need to be recovered. If this is greater than the network MTU for UDP then the packet will be * fragmented and can amplify the impact of loss. * * @return MTU in bytes for datagrams sent to the network. * @see Configuration#MTU_LENGTH_PROP_NAME */ public int mtuLength() { return mtuLength; } /** * MTU in bytes for datagrams sent to the network. Messages larger than this are fragmented. *

* Larger MTUs reduce system call overhead at the expense of possible increase in loss which * will need to be recovered. If this is greater than the network MTU for UDP then the packet will be * fragmented and can amplify the impact of loss. * * @param mtuLength in bytes for datagrams sent to the network. * @return this for a fluent API. * @see Configuration#MTU_LENGTH_PROP_NAME */ public Context mtuLength(final int mtuLength) { this.mtuLength = mtuLength; return this; } /** * MTU in bytes for datagrams sent over shared memory. Messages larger than this are fragmented. *

* Larger MTUs reduce fragmentation. If an IPC stream is recorded to be later sent over the network then * a large MTU may be an issue. * * @return MTU in bytes for message fragments. * @see Configuration#IPC_MTU_LENGTH_PROP_NAME */ public int ipcMtuLength() { return ipcMtuLength; } /** * MTU in bytes for datagrams sent over shared memory. Messages larger than this are fragmented. *

* Larger MTUs reduce fragmentation. If an IPC stream is recorded to be later sent over the network then * a large MTU may be an issue. * * @param ipcMtuLength in bytes for message fragments. * @return this for a fluent API. * @see Configuration#IPC_MTU_LENGTH_PROP_NAME */ public Context ipcMtuLength(final int ipcMtuLength) { this.ipcMtuLength = ipcMtuLength; return this; } /** * The {@link EpochClock} as a source of time in milliseconds for wall clock time. * * @return the {@link EpochClock} as a source of time in milliseconds for wall clock time. */ public EpochClock epochClock() { return epochClock; } /** * The {@link EpochClock} as a source of time in milliseconds for wall clock time. * * @param clock to be used. * @return this for a fluent API. */ public Context epochClock(final EpochClock clock) { epochClock = clock; return this; } /** * The {@link NanoClock} as a source of time in nanoseconds for measuring duration. * * @return the {@link NanoClock} as a source of time in nanoseconds for measuring duration. */ public NanoClock nanoClock() { return nanoClock; } /** * The {@link NanoClock} as a source of time in nanoseconds for measuring duration. * * @param clock to be used. * @return this for a fluent API. */ public Context nanoClock(final NanoClock clock) { nanoClock = clock; return this; } /** * The {@link CachedEpochClock} as a source of time in milliseconds for wall clock time. * * @return the {@link CachedEpochClock} as a source of time in milliseconds for wall clock time. */ public CachedEpochClock cachedEpochClock() { return cachedEpochClock; } /** * The {@link CachedEpochClock} as a source of time in milliseconds for wall clock time. * * @param clock to be used. * @return this for a fluent API. */ public Context cachedEpochClock(final CachedEpochClock clock) { cachedEpochClock = clock; return this; } /** * The {@link CachedNanoClock} as a source of time in nanoseconds for measuring duration. This is updated * once per work cycle of the {@link DriverConductor}. * * @return the {@link CachedNanoClock} as a source of time in nanoseconds for measuring duration. */ public CachedNanoClock cachedNanoClock() { return cachedNanoClock; } /** * The {@link CachedNanoClock} as a source of time in nanoseconds for measuring duration for the * {@link DriverConductor}. * * @param clock to be used. * @return this for a fluent API. */ public Context cachedNanoClock(final CachedNanoClock clock) { cachedNanoClock = clock; return this; } /** * The {@link CachedNanoClock} as a source of time in nanoseconds for measuring duration. This is updated * once per work cycle of the {@link Sender}. * * @return the {@link CachedNanoClock} as a source of time in nanoseconds for measuring duration. */ public CachedNanoClock senderCachedNanoClock() { return senderCachedNanoClock; } /** * The {@link CachedNanoClock} as a source of time in nanoseconds for measuring duration for the * {@link Sender}. * * @param clock to be used. * @return this for a fluent API. */ public Context senderCachedNanoClock(final CachedNanoClock clock) { senderCachedNanoClock = clock; return this; } /** * The {@link CachedNanoClock} as a source of time in nanoseconds for measuring duration. This is updated * once per work cycle of the {@link Receiver}. * * @return the {@link CachedNanoClock} as a source of time in nanoseconds for measuring duration. */ public CachedNanoClock receiverCachedNanoClock() { return receiverCachedNanoClock; } /** * The {@link CachedNanoClock} as a source of time in nanoseconds for measuring duration for the * {@link Receiver}. * * @param clock to be used. * @return this for a fluent API. */ public Context receiverCachedNanoClock(final CachedNanoClock clock) { receiverCachedNanoClock = clock; return this; } /** * {@link ThreadingMode} that should be used for the driver. * * @return {@link ThreadingMode} that should be used for the driver. * @see Configuration#THREADING_MODE_PROP_NAME */ public ThreadingMode threadingMode() { return threadingMode; } /** * {@link ThreadingMode} that should be used for the driver. * * @param threadingMode that should be used for the driver. * @return this for a fluent API. * @see Configuration#THREADING_MODE_PROP_NAME */ public Context threadingMode(final ThreadingMode threadingMode) { this.threadingMode = threadingMode; return this; } /** * {@link ThreadFactory} to be used for creating agent thread for the {@link Sender} when running in * {@link ThreadingMode#DEDICATED}. * * @return {@link ThreadFactory} to be used for creating agent thread for the {@link Sender}. */ public ThreadFactory senderThreadFactory() { return senderThreadFactory; } /** * {@link ThreadFactory} to be used for creating agent thread for the {@link Sender} when running in * {@link ThreadingMode#DEDICATED}. *

* If none is provided then this will default a simple new operation. * * @param factory to be used for creating agent thread for the {@link Sender}. * @return this for a fluent API. */ public Context senderThreadFactory(final ThreadFactory factory) { senderThreadFactory = factory; return this; } /** * {@link ThreadFactory} to be used for creating agent thread for the {@link Receiver} when running in * {@link ThreadingMode#DEDICATED}. * * @return {@link ThreadFactory} to be used for creating agent thread for the {@link Receiver}. */ public ThreadFactory receiverThreadFactory() { return receiverThreadFactory; } /** * {@link ThreadFactory} to be used for creating agent thread for the {@link Receiver} when running in * {@link ThreadingMode#DEDICATED}. *

* If none is provided then this will default a simple new operation. * * @param factory to be used for creating agent thread for the {@link Receiver}. * @return this for a fluent API. */ public Context receiverThreadFactory(final ThreadFactory factory) { receiverThreadFactory = factory; return this; } /** * {@link ThreadFactory} to be used for creating agent thread for the {@link DriverConductor} when running in * {@link ThreadingMode#DEDICATED} or {@link ThreadingMode#SHARED_NETWORK}. * * @return {@link ThreadFactory} to be used for creating agent thread for the {@link DriverConductor}. */ public ThreadFactory conductorThreadFactory() { return conductorThreadFactory; } /** * {@link ThreadFactory} to be used for creating agent thread for the {@link DriverConductor} when running in * {@link ThreadingMode#DEDICATED} or {@link ThreadingMode#SHARED_NETWORK}. *

* If none is provided then this will default a simple new operation. * * @param factory to be used for creating agent thread for the {@link DriverConductor}. * @return this for a fluent API. */ public Context conductorThreadFactory(final ThreadFactory factory) { conductorThreadFactory = factory; return this; } /** * {@link ThreadFactory} to be used for creating agent thread for the all driver agents as a * {@link CompositeAgent} when running in {@link ThreadingMode#SHARED}. * * @return {@link ThreadFactory} to be used for creating agent thread for the {@link CompositeAgent}. */ public ThreadFactory sharedThreadFactory() { return sharedThreadFactory; } /** * {@link ThreadFactory} to be used for creating agent thread for the all driver agents as a * {@link CompositeAgent} when running in {@link ThreadingMode#SHARED}. *

* If none is provided then this will default a simple new operation. * * @param factory to be used for creating agent thread for the {@link CompositeAgent}. * @return this for a fluent API. */ public Context sharedThreadFactory(final ThreadFactory factory) { sharedThreadFactory = factory; return this; } /** * {@link ThreadFactory} to be used for creating agent thread for the sender and receiver agents as a * {@link CompositeAgent} when running in {@link ThreadingMode#SHARED_NETWORK}. * * @return {@link ThreadFactory} to be used for creating agent thread for the {@link CompositeAgent}. */ public ThreadFactory sharedNetworkThreadFactory() { return sharedNetworkThreadFactory; } /** * {@link ThreadFactory} to be used for creating agent thread for the sender and receiver agents as a * {@link CompositeAgent} when running in {@link ThreadingMode#SHARED_NETWORK}. *

* If none is provided then this will default a simple new operation. * * @param factory to be used for creating agent thread for the {@link CompositeAgent}. * @return this for a fluent API. */ public Context sharedNetworkThreadFactory(final ThreadFactory factory) { sharedNetworkThreadFactory = factory; return this; } /** * {@link IdleStrategy} to be used by the {@link Sender} when in {@link ThreadingMode#DEDICATED}. * * @return {@link IdleStrategy} to be used by the {@link Sender} when in {@link ThreadingMode#DEDICATED}. * @see Configuration#SENDER_IDLE_STRATEGY_PROP_NAME */ public IdleStrategy senderIdleStrategy() { return senderIdleStrategy; } /** * {@link IdleStrategy} to be used by the {@link Sender} when in {@link ThreadingMode#DEDICATED}. * * @param strategy to be used by the {@link Sender} when in {@link ThreadingMode#DEDICATED}. * @return this for a fluent API. * @see Configuration#SENDER_IDLE_STRATEGY_PROP_NAME */ public Context senderIdleStrategy(final IdleStrategy strategy) { senderIdleStrategy = strategy; return this; } /** * {@link IdleStrategy} to be used by the {@link Receiver} when in {@link ThreadingMode#DEDICATED}. * * @return {@link IdleStrategy} used by the {@link Receiver} when in {@link ThreadingMode#DEDICATED}. * @see Configuration#RECEIVER_IDLE_STRATEGY_PROP_NAME */ public IdleStrategy receiverIdleStrategy() { return receiverIdleStrategy; } /** * {@link IdleStrategy} to be used by the {@link Receiver} when in {@link ThreadingMode#DEDICATED}. * * @param strategy to be used by the {@link Receiver} when in {@link ThreadingMode#DEDICATED}. * @return this for a fluent API. * @see Configuration#RECEIVER_IDLE_STRATEGY_PROP_NAME */ public Context receiverIdleStrategy(final IdleStrategy strategy) { receiverIdleStrategy = strategy; return this; } /** * {@link IdleStrategy} to be used by the {@link DriverConductor} when in {@link ThreadingMode#DEDICATED} * or {@link ThreadingMode#SHARED_NETWORK}. * * @return {@link IdleStrategy} used by the {@link DriverConductor} * @see Configuration#CONDUCTOR_IDLE_STRATEGY_PROP_NAME */ public IdleStrategy conductorIdleStrategy() { return conductorIdleStrategy; } /** * {@link IdleStrategy} to be used by the {@link DriverConductor} when in {@link ThreadingMode#DEDICATED} * or {@link ThreadingMode#SHARED_NETWORK}. * * @param strategy to be used by the {@link DriverConductor}. * @return this for a fluent API. * @see Configuration#CONDUCTOR_IDLE_STRATEGY_PROP_NAME */ public Context conductorIdleStrategy(final IdleStrategy strategy) { conductorIdleStrategy = strategy; return this; } /** * {@link IdleStrategy} to be used by the {@link Sender} and {@link Receiver} agents when in * {@link ThreadingMode#SHARED_NETWORK}. * * @return {@link IdleStrategy} used by the {@link Sender} and {@link Receiver}. * @see Configuration#SHARED_NETWORK_IDLE_STRATEGY_PROP_NAME */ public IdleStrategy sharedNetworkIdleStrategy() { return sharedNetworkIdleStrategy; } /** * {@link IdleStrategy} to be used by the {@link Sender} and {@link Receiver} agents when in * {@link ThreadingMode#SHARED_NETWORK}. * * @param strategy to be used by the {@link Sender} and {@link Receiver}. * @return this for a fluent API. * @see Configuration#SHARED_NETWORK_IDLE_STRATEGY_PROP_NAME */ public Context sharedNetworkIdleStrategy(final IdleStrategy strategy) { sharedNetworkIdleStrategy = strategy; return this; } /** * {@link IdleStrategy} to be used by the {@link Sender}, {@link Receiver} and {@link DriverConductor} * agents when in {@link ThreadingMode#SHARED}. * * @return {@link IdleStrategy} used by the {@link Sender}, {@link Receiver} and {@link DriverConductor}. * @see Configuration#SHARED_IDLE_STRATEGY_PROP_NAME */ public IdleStrategy sharedIdleStrategy() { return sharedIdleStrategy; } /** * {@link IdleStrategy} to be used by the {@link Sender}, {@link Receiver} and {@link DriverConductor} * agents when in {@link ThreadingMode#SHARED}. * * @param strategy to be used by the {@link Sender}, {@link Receiver} and {@link DriverConductor}. * @return this for a fluent API. * @see Configuration#SHARED_IDLE_STRATEGY_PROP_NAME */ public Context sharedIdleStrategy(final IdleStrategy strategy) { sharedIdleStrategy = strategy; return this; } /** * Supplier of dynamically created {@link SendChannelEndpoint} subclasses for specialising interactions * with the send side of a network channel. * * @return the supplier of dynamically created {@link SendChannelEndpoint} subclasses. * @see Configuration#SEND_CHANNEL_ENDPOINT_SUPPLIER_PROP_NAME */ public SendChannelEndpointSupplier sendChannelEndpointSupplier() { return sendChannelEndpointSupplier; } /** * Supplier of dynamically created {@link SendChannelEndpoint} subclasses for specialising interactions * with the send side of a network channel. * * @param supplier of dynamically created {@link SendChannelEndpoint} subclasses. * @return this for a fluent API. * @see Configuration#SEND_CHANNEL_ENDPOINT_SUPPLIER_PROP_NAME */ public Context sendChannelEndpointSupplier(final SendChannelEndpointSupplier supplier) { sendChannelEndpointSupplier = supplier; return this; } /** * Supplier of dynamically created {@link ReceiveChannelEndpoint} subclasses for specialising interactions * with the receiving side of a network channel. * * @return the supplier of dynamically created {@link ReceiveChannelEndpoint} subclasses. * @see Configuration#RECEIVE_CHANNEL_ENDPOINT_SUPPLIER_PROP_NAME */ public ReceiveChannelEndpointSupplier receiveChannelEndpointSupplier() { return receiveChannelEndpointSupplier; } /** * Supplier of dynamically created {@link ReceiveChannelEndpoint} subclasses for specialising interactions * with the receiving side of a network channel. * * @param supplier of dynamically created {@link ReceiveChannelEndpoint} subclasses. * @return this for a fluent API. * @see Configuration#RECEIVE_CHANNEL_ENDPOINT_SUPPLIER_PROP_NAME */ public Context receiveChannelEndpointSupplier(final ReceiveChannelEndpointSupplier supplier) { receiveChannelEndpointSupplier = supplier; return this; } /** * The thread local buffers and associated objects for use by subclasses of {@link ReceiveChannelEndpoint}. * * @return thread local buffers and associated objects for use by subclasses of {@link ReceiveChannelEndpoint}. */ public ReceiveChannelEndpointThreadLocals receiveChannelEndpointThreadLocals() { return receiveChannelEndpointThreadLocals; } /** * The thread local buffers and associated objects for use by subclasses of {@link ReceiveChannelEndpoint}. * * @param threadLocals for use by subclasses of {@link ReceiveChannelEndpoint}. * @return this for a fluent API. */ public Context receiveChannelEndpointThreadLocals(final ReceiveChannelEndpointThreadLocals threadLocals) { receiveChannelEndpointThreadLocals = threadLocals; return this; } /** * The temporary buffer than can be used to build up counter labels to avoid allocation. * * @return the temporary buffer than can be used to build up counter labels to avoid allocation. */ public MutableDirectBuffer tempBuffer() { return tempBuffer; } /** * Set the temporary buffer than can be used to build up counter labels to avoid allocation. * * @param tempBuffer to be used to avoid allocation. * @return the temporary buffer than can be used to build up counter labels to avoid allocation. */ public Context tempBuffer(final MutableDirectBuffer tempBuffer) { this.tempBuffer = tempBuffer; return this; } /** * Supplier of dynamically created {@link FlowControl} strategies for unicast connections. * * @return supplier of dynamically created {@link FlowControl} strategies for unicast connections. * @see Configuration#UNICAST_FLOW_CONTROL_STRATEGY_SUPPLIER_PROP_NAME */ public FlowControlSupplier unicastFlowControlSupplier() { return unicastFlowControlSupplier; } /** * Supplier of dynamically created {@link FlowControl} strategies for unicast connections. * * @param flowControlSupplier of {@link FlowControl} strategies for unicast connections. * @return this for a fluent API. * @see Configuration#UNICAST_FLOW_CONTROL_STRATEGY_SUPPLIER_PROP_NAME */ public Context unicastFlowControlSupplier(final FlowControlSupplier flowControlSupplier) { unicastFlowControlSupplier = flowControlSupplier; return this; } /** * Supplier of dynamically created {@link FlowControl} strategies for multicast connections. * * @return supplier of dynamically created {@link FlowControl} strategies for multicast connections. * @see Configuration#MULTICAST_FLOW_CONTROL_STRATEGY_SUPPLIER_PROP_NAME */ public FlowControlSupplier multicastFlowControlSupplier() { return multicastFlowControlSupplier; } /** * Supplier of dynamically created {@link FlowControl} strategies for multicast connections. * * @param flowControlSupplier of {@link FlowControl} strategies for multicast connections. * @return this for a fluent API. * @see Configuration#MULTICAST_FLOW_CONTROL_STRATEGY_SUPPLIER_PROP_NAME */ public Context multicastFlowControlSupplier(final FlowControlSupplier flowControlSupplier) { multicastFlowControlSupplier = flowControlSupplier; return this; } /** * Timeout for min multicast flow control strategy. * * @return timeout in ns. * @see Configuration#FLOW_CONTROL_RECEIVER_TIMEOUT_PROP_NAME */ public long flowControlReceiverTimeoutNs() { return flowControlReceiverTimeoutNs; } /** * Timeout for min multicast flow control strategy. * * @param timeoutNs in ns. * @return this for a fluent API. * @see Configuration#FLOW_CONTROL_RECEIVER_TIMEOUT_PROP_NAME */ public Context flowControlReceiverTimeoutNs(final long timeoutNs) { this.flowControlReceiverTimeoutNs = timeoutNs; return this; } /** * Application specific feedback used to identify a receiver group when using a * {@link TaggedMulticastFlowControl} strategy which is added to Status Messages (SMs). *

* Replaced by {@link #receiverGroupTag()}. * * @return Application specific feedback used to identify receiver group for flow control. * @see Configuration#SM_APPLICATION_SPECIFIC_FEEDBACK_PROP_NAME */ @Deprecated public byte[] applicationSpecificFeedback() { return applicationSpecificFeedback; } /** * Application specific feedback used to identify a receiver group when using a * {@link TaggedMulticastFlowControl} strategy which is added to Status Messages (SMs). *

* Replaced by {@link #receiverGroupTag(Long)}. * * @param asfBytes for identifying a receiver group. * @return this for a fluent API. * @see Configuration#SM_APPLICATION_SPECIFIC_FEEDBACK_PROP_NAME */ @Deprecated public Context applicationSpecificFeedback(final byte[] asfBytes) { this.applicationSpecificFeedback = asfBytes; return this; } /** * Supplier of dynamically created {@link CongestionControl} strategies for individual connections. * * @return supplier of dynamically created {@link CongestionControl} strategies for individual connections. * @see Configuration#CONGESTION_CONTROL_STRATEGY_SUPPLIER_PROP_NAME */ public CongestionControlSupplier congestionControlSupplier() { return congestionControlSupplier; } /** * Supplier of dynamically created {@link CongestionControl} strategies for individual connections. * * @param supplier of dynamically created {@link CongestionControl} strategies for individual connections. * @return this for a fluent API. * @see Configuration#CONGESTION_CONTROL_STRATEGY_SUPPLIER_PROP_NAME */ public Context congestControlSupplier(final CongestionControlSupplier supplier) { this.congestionControlSupplier = supplier; return this; } /** * {@link ErrorHandler} to be used for reporting errors during {@link Agent}s operations. * * @return the {@link ErrorHandler} to be used for reporting errors during {@link Agent}s operations. */ public ErrorHandler errorHandler() { return errorHandler; } /** * {@link ErrorHandler} to be used for reporting errors during {@link Agent}s operations. *

* The default {@link ErrorHandler} will delegate to the {@link #errorLog()} and output to {@link System#err} * if the log is full. *

* Note: {@link ErrorHandler} should be thread safe. * * @param errorHandler to be used for reporting errors during {@link Agent}s operations. * @return this for a fluent API. */ public Context errorHandler(final ErrorHandler errorHandler) { this.errorHandler = errorHandler; return this; } /** * Log to which exceptions are recorded. * * @return log to which exceptions are recorded. */ public DistinctErrorLog errorLog() { return errorLog; } /** * Log to which exceptions are recorded. * * @param errorLog to which exceptions are recorded. * @return this for a fluent API. */ public Context errorLog(final DistinctErrorLog errorLog) { this.errorLog = errorLog; return this; } /** * Should a {@link ConcurrentCountersManager} be used to allow for cross thread usage. * * @return true if a {@link ConcurrentCountersManager} should be used otherwise false. */ public boolean useConcurrentCountersManager() { return useConcurrentCountersManager; } /** * Should a {@link ConcurrentCountersManager} be used to allow for cross thread usage. *

* The default is to use a normal {@link CountersManager} from only the {@link DriverConductor}. If the * {@link MediaDriver} is to be composed into another services that allocates counters then this should be * concurrent. * * @param useConcurrentCountersManager true if a {@link ConcurrentCountersManager} should be used. * @return this for a fluent API. */ public Context useConcurrentCountersManager(final boolean useConcurrentCountersManager) { this.useConcurrentCountersManager = useConcurrentCountersManager; return this; } /** * Get the {@link CountersManager} that has been concluded for this context. * * @return the {@link CountersManager} that has been concluded for this context. */ public CountersManager countersManager() { return countersManager; } /** * Set the {@link CountersManager} to override the one that would have been concluded. * * @param countersManager to override the one that would have been concluded. * @return this for a fluent API. */ public Context countersManager(final CountersManager countersManager) { this.countersManager = countersManager; return this; } /** * The {@link SystemCounters} for the driver for recording aggregate events of system status. * * @return the {@link SystemCounters} for the driver for recording aggregate events of system status. */ public SystemCounters systemCounters() { return systemCounters; } /** * The {@link SystemCounters} for the driver for recording aggregate events of system status. *

* The default should only be overridden for testing. * * @param systemCounters for the driver for recording aggregate events of system status. * @return this for a fluent API. */ public Context systemCounters(final SystemCounters systemCounters) { this.systemCounters = systemCounters; return this; } /** * {@link LossReport} for identifying loss issues on specific connections. * * @return {@link LossReport} for identifying loss issues on specific connections. */ LossReport lossReport() { return lossReport; } /** * {@link LossReport} for identifying loss issues on specific connections. * * @param lossReport for identifying loss issues on specific connections. * @return this for a fluent API. */ Context lossReport(final LossReport lossReport) { this.lossReport = lossReport; return this; } /** * Low end of the publication reserved session id range which will not be automatically assigned. * * @return low end of the publication reserved session id range which will not be automatically assigned. * @see #publicationReservedSessionIdHigh() * @see Configuration#PUBLICATION_RESERVED_SESSION_ID_LOW_PROP_NAME */ public int publicationReservedSessionIdLow() { return publicationReservedSessionIdLow; } /** * Low end of the publication reserved session id range which will not be automatically assigned. * * @param sessionId for low end of the publication reserved session id range which will not be automatically * assigned. * @return this for fluent API. * @see #publicationReservedSessionIdHigh(int) * @see Configuration#PUBLICATION_RESERVED_SESSION_ID_LOW_PROP_NAME */ public Context publicationReservedSessionIdLow(final int sessionId) { publicationReservedSessionIdLow = sessionId; return this; } /** * High end of the publication reserved session id range which will not be automatically assigned. * * @return high end of the publication reserved session id range which will not be automatically assigned. * @see #publicationReservedSessionIdLow() * @see Configuration#PUBLICATION_RESERVED_SESSION_ID_HIGH_PROP_NAME */ public int publicationReservedSessionIdHigh() { return publicationReservedSessionIdHigh; } /** * High end of the publication reserved session id range which will not be automatically assigned. * * @param sessionId for high end of the publication reserved session id range which will not be automatically * assigned. * @return this for fluent API. * @see #publicationReservedSessionIdLow(int) * @see Configuration#PUBLICATION_RESERVED_SESSION_ID_HIGH_PROP_NAME */ public Context publicationReservedSessionIdHigh(final int sessionId) { publicationReservedSessionIdHigh = sessionId; return this; } /** * {@link FeedbackDelayGenerator} for controlling the delay before sending a retransmit frame. * * @return {@link FeedbackDelayGenerator} for controlling the delay before sending a retransmit frame. * @see Configuration#RETRANSMIT_UNICAST_DELAY_PROP_NAME */ public FeedbackDelayGenerator retransmitUnicastDelayGenerator() { return retransmitUnicastDelayGenerator; } /** * Set the {@link FeedbackDelayGenerator} for controlling the delay before sending a retransmit frame. * * @param feedbackDelayGenerator for controlling the delay before sending a retransmit frame. * @return this for a fluent API * @see Configuration#RETRANSMIT_UNICAST_DELAY_PROP_NAME */ public Context retransmitUnicastDelayGenerator(final FeedbackDelayGenerator feedbackDelayGenerator) { retransmitUnicastDelayGenerator = feedbackDelayGenerator; return this; } /** * {@link FeedbackDelayGenerator} for controlling the linger after a retransmit. * * @return {@link FeedbackDelayGenerator} for controlling the linger after a retransmit. * @see Configuration#RETRANSMIT_UNICAST_LINGER_PROP_NAME */ public FeedbackDelayGenerator retransmitUnicastLingerGenerator() { return retransmitUnicastLingerGenerator; } /** * Set the {@link FeedbackDelayGenerator} for controlling the time to linger after a retransmit frame is sent. * * @param feedbackDelayGenerator for controlling the linger after a retransmit. * @return this for a fluent API * @see Configuration#RETRANSMIT_UNICAST_LINGER_PROP_NAME */ public Context retransmitUnicastLingerGenerator(final FeedbackDelayGenerator feedbackDelayGenerator) { retransmitUnicastLingerGenerator = feedbackDelayGenerator; return this; } /** * {@link FeedbackDelayGenerator} for controlling the delay of sending NAK feedback on unicast. * * @return {@link FeedbackDelayGenerator} for controlling the delay of sending NAK feedback. * @see Configuration#NAK_UNICAST_DELAY_PROP_NAME */ public FeedbackDelayGenerator unicastFeedbackDelayGenerator() { return unicastFeedbackDelayGenerator; } /** * Set the {@link FeedbackDelayGenerator} for controlling the delay of sending NAK feedback on unicast. * * @param feedbackDelayGenerator for controlling the delay of sending NAK feedback. * @return this for a fluent API * @see Configuration#NAK_UNICAST_DELAY_PROP_NAME */ public Context unicastFeedbackDelayGenerator(final FeedbackDelayGenerator feedbackDelayGenerator) { unicastFeedbackDelayGenerator = feedbackDelayGenerator; return this; } /** * {@link FeedbackDelayGenerator} for controlling the delay of sending NAK feedback on multicast. * * @return {@link FeedbackDelayGenerator} for controlling the delay of sending NAK feedback. * @see Configuration#NAK_MULTICAST_MAX_BACKOFF_PROP_NAME * @see Configuration#NAK_MULTICAST_GROUP_SIZE_PROP_NAME */ public FeedbackDelayGenerator multicastFeedbackDelayGenerator() { return multicastFeedbackDelayGenerator; } /** * Set the {@link FeedbackDelayGenerator} for controlling the delay of sending NAK feedback on multicast. * * @param feedbackDelayGenerator for controlling the delay of sending NAK feedback. * @return this for a fluent API * @see Configuration#NAK_MULTICAST_MAX_BACKOFF_PROP_NAME * @see Configuration#NAK_MULTICAST_GROUP_SIZE_PROP_NAME */ public Context multicastFeedbackDelayGenerator(final FeedbackDelayGenerator feedbackDelayGenerator) { multicastFeedbackDelayGenerator = feedbackDelayGenerator; return this; } /** * Set the {@link Runnable} that is called when the {@link MediaDriver} processes a valid termination request. * * @param terminationHook that can be used to terminate a driver. * @return this for a fluent API. */ public Context terminationHook(final Runnable terminationHook) { this.terminationHook = terminationHook; return this; } /** * Get the {@link Runnable} that is called when the {@link MediaDriver} processes a valid termination request. *

* The default action is nothing. * * @return the {@link Runnable} that can be used to terminate a consensus module. */ public Runnable terminationHook() { return terminationHook; } /** * Set the {@link TerminationValidator} to be used to validate termination requests. * * @param validator to validate termination requests. * @return this for a fluent API. */ public Context terminationValidator(final TerminationValidator validator) { this.terminationValidator = validator; return this; } /** * Get the {@link TerminationValidator} to be used to validate termination requests. * * @return {@link TerminationValidator} to validate termination requests. */ public TerminationValidator terminationValidator() { return terminationValidator; } /** * Get the ratio for sending data to polling status messages in the Sender. * * @return ratio for sending data to polling status messages in the Sender. */ public int sendToStatusMessagePollRatio() { return sendToStatusMessagePollRatio; } /** * Set the ratio for sending data to polling status messages in the Sender. * * @param ratio to use. * @return this for fluent API. */ public Context sendToStatusMessagePollRatio(final int ratio) { this.sendToStatusMessagePollRatio = ratio; return this; } /** * Get the group tag (gtag) to be sent in Status Messages from the Receiver. * * @return group tag value or null if not set. * @see Configuration#RECEIVER_GROUP_TAG_PROP_NAME */ public Long receiverGroupTag() { return receiverGroupTag; } /** * Set the group tag (gtag) to be sent in Status Messages from the Receiver. * * @param groupTag value to sent in Status Messages from the receiver or null if not set. * @return this for fluent API. * @see Configuration#RECEIVER_GROUP_TAG_PROP_NAME */ public Context receiverGroupTag(final Long groupTag) { this.receiverGroupTag = groupTag; return this; } /** * Get the default group tag (gtag) to be used by the tagged flow control strategy. * * @return group tag value or null if not set. * @see Configuration#FLOW_CONTROL_GROUP_TAG_PROP_NAME */ public long flowControlGroupTag() { return flowControlGroupTag; } /** * Set the default group tag (gtag) to be used by the tagged flow control strategy. * * @param groupTag value to use by default by the tagged flow control strategy. * @return this for fluent API. * @see Configuration#FLOW_CONTROL_GROUP_TAG_PROP_NAME */ public Context flowControlGroupTag(final long groupTag) { this.flowControlGroupTag = groupTag; return this; } /** * Get the default min group size used by flow control strategies to indicate connectivity. * * @return required group size. * @see Configuration#FLOW_CONTROL_GROUP_MIN_SIZE_PROP_NAME */ public int flowControlGroupMinSize() { return flowControlGroupMinSize; } /** * Set the default min group size used by flow control strategies to indicate connectivity. * * @param groupSize minimum required group size used by the tagged flow control strategy. * @return this for fluent API. * @see Configuration#FLOW_CONTROL_GROUP_MIN_SIZE_PROP_NAME */ public Context flowControlGroupMinSize(final int groupSize) { this.flowControlGroupMinSize = groupSize; return this; } /** * Get the {@link NameResolver} to use for resolving endpoints and control names. * * @return {@link NameResolver} to use for resolving endpoints and control names. */ public NameResolver nameResolver() { return nameResolver; } /** * Set the {@link NameResolver} to use for resolving endpoints and control names. * * @param nameResolver to use for resolving endpoints and control names. * @return this for fluent API. */ public Context nameResolver(final NameResolver nameResolver) { this.nameResolver = nameResolver; return this; } /** * Get the name of the {@link MediaDriver} for name resolver purposes. * * @return name of the {@link MediaDriver}. * @see Configuration#RESOLVER_NAME_PROP_NAME */ public String resolverName() { return resolverName; } /** * Set the name of the {@link MediaDriver} for name resolver purposes. * * @param resolverName for the driver. * @return this for a fluent API. * @see Configuration#RESOLVER_NAME_PROP_NAME */ public Context resolverName(final String resolverName) { this.resolverName = resolverName; return this; } /** * Get the interface of the {@link MediaDriver} for name resolver purposes. *

* The format is hostname:port and follows the URI format for the interface parameter. If set to null, * then the name resolver will not be used. * * @return interface of the {@link MediaDriver}. * @see Configuration#RESOLVER_INTERFACE_PROP_NAME * @see CommonContext#INTERFACE_PARAM_NAME */ public String resolverInterface() { return resolverInterface; } /** * Set the interface of the {@link MediaDriver} for name resolver purposes. *

* The format is hostname:port and follows the URI format for the interface parameter. If set to null, * then the name resolver will not be used. * * @param resolverInterface to use for the name resolver. * @return this for fluent API. * @see Configuration#RESOLVER_INTERFACE_PROP_NAME * @see CommonContext#INTERFACE_PARAM_NAME */ public Context resolverInterface(final String resolverInterface) { this.resolverInterface = resolverInterface; return this; } /** * Get the bootstrap neighbor of the {@link MediaDriver} for name resolver purposes. *

* The format is comma separated list of {@code hostname:port} pairs. and follows the URI format for the * endpoint parameter. * * @return bootstrap neighbor of the {@link MediaDriver}. * @see Configuration#RESOLVER_BOOTSTRAP_NEIGHBOR_PROP_NAME * @see CommonContext#ENDPOINT_PARAM_NAME */ public String resolverBootstrapNeighbor() { return resolverBootstrapNeighbor; } /** * Set the bootstrap neighbor of the {@link MediaDriver} for name resolver purposes. *

* The format is hostname:port and follows the URI format for the endpoint parameter. * * @param resolverBootstrapNeighbor to use for the name resolver. * @return this for fluent API. * @see Configuration#RESOLVER_BOOTSTRAP_NEIGHBOR_PROP_NAME * @see CommonContext#ENDPOINT_PARAM_NAME */ public Context resolverBootstrapNeighbor(final String resolverBootstrapNeighbor) { this.resolverBootstrapNeighbor = resolverBootstrapNeighbor; return this; } /** * Get the interval for checking if a re-resolution for endpoints and controls should be done. *

* A value of 0 turns off checks and re-resolutions. * * @return timeout in ns. * @see Configuration#RE_RESOLUTION_CHECK_INTERVAL_PROP_NAME * @see Configuration#RE_RESOLUTION_CHECK_INTERVAL_DEFAULT_NS */ public long reResolutionCheckIntervalNs() { return reResolutionCheckIntervalNs; } /** * Set the interval for checking if a re-resolution for endpoints and controls should be done. *

* A value of 0 turns off checks and re-resolutions. * * @param reResolutionCheckIntervalNs to use for check * @return this for fluent API. * @see Configuration#RE_RESOLUTION_CHECK_INTERVAL_PROP_NAME * @see Configuration#RE_RESOLUTION_CHECK_INTERVAL_DEFAULT_NS */ public Context reResolutionCheckIntervalNs(final long reResolutionCheckIntervalNs) { this.reResolutionCheckIntervalNs = reResolutionCheckIntervalNs; return this; } /** * Set a threshold for the conductor work cycle time which when exceed it will increment the * {@link io.aeron.driver.status.SystemCounterDescriptor#CONDUCTOR_CYCLE_TIME_THRESHOLD_EXCEEDED} counter. * * @param thresholdNs value in nanoseconds * @return this for fluent API. * @see Configuration#CONDUCTOR_CYCLE_THRESHOLD_PROP_NAME * @see Configuration#CONDUCTOR_CYCLE_THRESHOLD_DEFAULT_NS */ public Context conductorCycleThresholdNs(final long thresholdNs) { this.conductorCycleThresholdNs = thresholdNs; return this; } /** * Threshold for the conductor work cycle time which when exceed it will increment the * {@link io.aeron.driver.status.SystemCounterDescriptor#CONDUCTOR_CYCLE_TIME_THRESHOLD_EXCEEDED} counter. * * @return threshold to track for the conductor work cycle time. */ public long conductorCycleThresholdNs() { return conductorCycleThresholdNs; } /** * Set the clock to be used to record channel receive timestamps. * * @param clock to provide ns-resolution timestamps since the epoch. * @return this for a fluent API. */ public Context channelReceiveTimestampClock(final EpochNanoClock clock) { channelReceiveTimestampClock = clock; return this; } /** * Set a threshold for the sender work cycle time which when exceed it will increment the * {@link io.aeron.driver.status.SystemCounterDescriptor#SENDER_CYCLE_TIME_THRESHOLD_EXCEEDED} counter. * * @param thresholdNs value in nanoseconds * @return this for fluent API. * @see Configuration#SENDER_CYCLE_THRESHOLD_PROP_NAME * @see Configuration#SENDER_CYCLE_THRESHOLD_DEFAULT_NS */ public Context senderCycleThresholdNs(final long thresholdNs) { this.senderCycleThresholdNs = thresholdNs; return this; } /** * Threshold for the sender work cycle time which when exceed it will increment the * {@link io.aeron.driver.status.SystemCounterDescriptor#SENDER_CYCLE_TIME_THRESHOLD_EXCEEDED} counter. * * @return threshold to track for the sender work cycle time. */ public long senderCycleThresholdNs() { return senderCycleThresholdNs; } /** * Set a threshold for the receiver work cycle time which when exceed it will increment the * {@link io.aeron.driver.status.SystemCounterDescriptor#RECEIVER_CYCLE_TIME_THRESHOLD_EXCEEDED} counter. * * @param thresholdNs value in nanoseconds * @return this for fluent API. * @see Configuration#RECEIVER_CYCLE_THRESHOLD_PROP_NAME * @see Configuration#RECEIVER_CYCLE_THRESHOLD_DEFAULT_NS */ public Context receiverCycleThresholdNs(final long thresholdNs) { this.receiverCycleThresholdNs = thresholdNs; return this; } /** * Threshold for the receiver work cycle time which when exceed it will increment the * {@link io.aeron.driver.status.SystemCounterDescriptor#RECEIVER_CYCLE_TIME_THRESHOLD_EXCEEDED} counter. * * @return threshold to track for the receiver work cycle time. */ public long receiverCycleThresholdNs() { return receiverCycleThresholdNs; } /** * Set a threshold for the {@link NameResolver} which when exceed it will increment the * {@link io.aeron.driver.status.SystemCounterDescriptor#NAME_RESOLVER_TIME_THRESHOLD_EXCEEDED} counter. * * @param thresholdNs value in nanoseconds * @return this for fluent API. * @see Configuration#NAME_RESOLVER_THRESHOLD_PROP_NAME * @see Configuration#NAME_RESOLVER_THRESHOLD_DEFAULT_NS */ public Context nameResolverThresholdNs(final long thresholdNs) { this.nameResolverThresholdNs = thresholdNs; return this; } /** * Threshold for the {@link NameResolver} which when exceed it will increment the * {@link io.aeron.driver.status.SystemCounterDescriptor#NAME_RESOLVER_TIME_THRESHOLD_EXCEEDED} counter. * * @return threshold to track for the name resolution. */ public long nameResolverThresholdNs() { return nameResolverThresholdNs; } /** * Maximum number of {@link DriverManagedResource}s to free within a single duty cycle of the conductor. * * @param resourceFreeLimit number of resources to limit to. * @return this for a fluent API. * @see Configuration#resourceFreeLimit() * @see Configuration#RESOURCE_FREE_LIMIT_PROP_NAME * @see Configuration#RESOURCE_FREE_LIMIT_DEFAULT * @since 1.41.0 */ public Context resourceFreeLimit(final int resourceFreeLimit) { this.resourceFreeLimit = resourceFreeLimit; return this; } /** * Maximum number of {@link DriverManagedResource}s to free within a single duty cycle of the conductor. * * @return limit on the number of resources that can be freed. * @since 1.41.0 */ public int resourceFreeLimit() { return resourceFreeLimit; } /** * Clock used record channel receive timestamps. * * @return a clock instance. */ public EpochNanoClock channelReceiveTimestampClock() { return channelReceiveTimestampClock; } /** * Set the clock to be used to record channel send timestamps. * * @param clock to provide ns-resolution timestamps since the epoch. * @return this for a fluent API. */ public Context channelSendTimestampClock(final EpochNanoClock clock) { channelSendTimestampClock = clock; return this; } /** * Duty cycle tracker used for the conductor. * * @return conductor duty cycle tracker. */ public DutyCycleTracker conductorDutyCycleTracker() { return conductorDutyCycleTracker; } /** * Set the duty cycle tracker used for the conductor. * * @param dutyCycleTracker for the conductor. * @return this for a fluent API. */ public Context conductorDutyCycleTracker(final DutyCycleTracker dutyCycleTracker) { this.conductorDutyCycleTracker = dutyCycleTracker; return this; } /** * Duty cycle tracker used for the sender. * * @return sender duty cycle tracker. */ public DutyCycleTracker senderDutyCycleTracker() { return senderDutyCycleTracker; } /** * Set the duty cycle tracker used for the sender. * * @param dutyCycleTracker for the sender. * @return this for a fluent API. */ public Context senderDutyCycleTracker(final DutyCycleTracker dutyCycleTracker) { this.senderDutyCycleTracker = dutyCycleTracker; return this; } /** * Duty cycle tracker used for the receiver. * * @return receiver duty cycle tracker. */ public DutyCycleTracker receiverDutyCycleTracker() { return receiverDutyCycleTracker; } /** * Set the duty cycle tracker used for the receiver. * * @param dutyCycleTracker for the receiver. * @return this for a fluent API. */ public Context receiverDutyCycleTracker(final DutyCycleTracker dutyCycleTracker) { this.receiverDutyCycleTracker = dutyCycleTracker; return this; } /** * Duty cycle tracker used for the {@link NameResolver}. * * @return {@link NameResolver} duty cycle tracker. */ public DutyCycleTracker nameResolverTimeTracker() { return nameResolverTimeTracker; } /** * Set the duty cycle tracker used for the {@link NameResolver}. * * @param dutyCycleTracker for the {@link NameResolver}. * @return this for a fluent API. */ public Context nameResolverTimeTracker(final DutyCycleTracker dutyCycleTracker) { this.nameResolverTimeTracker = dutyCycleTracker; return this; } /** * Wildcard port range used for the Sender * * @return port range as a string in the format "low high". */ public String senderWildcardPortRange() { return senderWildcardPortRange; } /** * Set the wildcard port range to be used for the Sender. *

* Format is a string in "low high". With low being the low port value and high being the high port value. For * example, "100 200". A null value or a value of "0 0" will use OS wildcard functionality. * * @param portRange as a string in the format "low high". * @return this for fluent API. * @see Configuration#SENDER_WILDCARD_PORT_RANGE_PROP_NAME */ public Context senderWildcardPortRange(final String portRange) { this.senderWildcardPortRange = portRange; return this; } /** * Wildcard port range used for the Receiver * * @return port range as a string in the format "low high". */ public String receiverWildcardPortRange() { return receiverWildcardPortRange; } /** * Set the wildcard port range to be used for the Receiver. *

* Format is a string in "low high". With low being the low port value and high being the high port value. For * example, "100 200". A null value or a value of "0 0" will use OS wildcard functionality. * * @param portRange as a string in the format "low high". * @return this for fluent API. * @see Configuration#RECEIVER_WILDCARD_PORT_RANGE_PROP_NAME */ public Context receiverWildcardPortRange(final String portRange) { this.receiverWildcardPortRange = portRange; return this; } /** * Port manager used for the {@link Sender}. * * @return Sender {@link PortManager}. */ public PortManager senderPortManager() { return senderPortManager; } /** * Set the {@link PortManager} used for the {@link Sender}. * * @param portManager for the {@link Sender} * @return this for a fluent API. */ public Context senderPortManager(final PortManager portManager) { this.senderPortManager = portManager; return this; } /** * Port manager used for the {@link Receiver}. * * @return Receiver {@link PortManager}. */ public PortManager receiverPortManager() { return receiverPortManager; } /** * Set the {@link PortManager} used for the {@link Receiver}. * * @param portManager for the {@link Receiver} * @return this for a fluent API. */ public Context receiverPortManager(final PortManager portManager) { this.receiverPortManager = portManager; return this; } /** * Clock used record channel send timestamps. * * @return a clock instance. */ public EpochNanoClock channelSendTimestampClock() { return channelSendTimestampClock; } OneToOneConcurrentArrayQueue receiverCommandQueue() { return receiverCommandQueue; } Context receiverCommandQueue(final OneToOneConcurrentArrayQueue receiverCommandQueue) { this.receiverCommandQueue = receiverCommandQueue; return this; } OneToOneConcurrentArrayQueue senderCommandQueue() { return senderCommandQueue; } Context senderCommandQueue(final OneToOneConcurrentArrayQueue senderCommandQueue) { this.senderCommandQueue = senderCommandQueue; return this; } ManyToOneConcurrentArrayQueue driverCommandQueue() { return driverCommandQueue; } Context driverCommandQueue(final ManyToOneConcurrentArrayQueue queue) { this.driverCommandQueue = queue; return this; } ClientProxy clientProxy() { return clientProxy; } Context clientProxy(final ClientProxy clientProxy) { this.clientProxy = clientProxy; return this; } RingBuffer toDriverCommands() { return toDriverCommands; } Context toDriverCommands(final RingBuffer toDriverCommands) { this.toDriverCommands = toDriverCommands; return this; } LogFactory logFactory() { return logFactory; } Context logFactory(final LogFactory logFactory) { this.logFactory = logFactory; return this; } DataTransportPoller dataTransportPoller() { return dataTransportPoller; } Context dataTransportPoller(final DataTransportPoller transportPoller) { this.dataTransportPoller = transportPoller; return this; } ControlTransportPoller controlTransportPoller() { return controlTransportPoller; } Context controlTransportPoller(final ControlTransportPoller transportPoller) { this.controlTransportPoller = transportPoller; return this; } ReceiverProxy receiverProxy() { return receiverProxy; } Context receiverProxy(final ReceiverProxy receiverProxy) { this.receiverProxy = receiverProxy; return this; } SenderProxy senderProxy() { return senderProxy; } Context senderProxy(final SenderProxy senderProxy) { this.senderProxy = senderProxy; return this; } DriverConductorProxy driverConductorProxy() { return driverConductorProxy; } Context driverConductorProxy(final DriverConductorProxy driverConductorProxy) { this.driverConductorProxy = driverConductorProxy; return this; } int osDefaultSocketRcvbufLength() { resolveOsSocketBufLengths(); return osDefaultSocketRcvbufLength; } int osMaxSocketRcvbufLength() { resolveOsSocketBufLengths(); return osMaxSocketRcvbufLength; } int osDefaultSocketSndbufLength() { resolveOsSocketBufLengths(); return osDefaultSocketSndbufLength; } int osMaxSocketSndbufLength() { resolveOsSocketBufLengths(); return osMaxSocketSndbufLength; } void resolveOsSocketBufLengths() { if (Aeron.NULL_VALUE != osMaxSocketRcvbufLength) { return; } try (DatagramChannel probe = DatagramChannel.open()) { osDefaultSocketSndbufLength = probe.getOption(StandardSocketOptions.SO_SNDBUF); probe.setOption(StandardSocketOptions.SO_SNDBUF, Integer.MAX_VALUE); osMaxSocketSndbufLength = probe.getOption(StandardSocketOptions.SO_SNDBUF); osDefaultSocketRcvbufLength = probe.getOption(StandardSocketOptions.SO_RCVBUF); probe.setOption(StandardSocketOptions.SO_RCVBUF, Integer.MAX_VALUE); osMaxSocketRcvbufLength = probe.getOption(StandardSocketOptions.SO_RCVBUF); } catch (final IOException ex) { throw new AeronException("probe socket: " + ex, ex); } } @SuppressWarnings({ "MethodLength", "deprecation" }) void concludeNullProperties() { if (null == tempBuffer) { tempBuffer = new UnsafeBuffer(new byte[METADATA_LENGTH]); } if (null == epochClock) { epochClock = SystemEpochClock.INSTANCE; } if (null == nanoClock) { nanoClock = SystemNanoClock.INSTANCE; } if (null == cachedEpochClock) { cachedEpochClock = new CachedEpochClock(); } if (null == cachedNanoClock) { cachedNanoClock = new CachedNanoClock(); } if (null == senderCachedNanoClock) { senderCachedNanoClock = new CachedNanoClock(); } if (null == receiverCachedNanoClock) { receiverCachedNanoClock = new CachedNanoClock(); } if (null == unicastFlowControlSupplier) { unicastFlowControlSupplier = Configuration.unicastFlowControlSupplier(); } if (null == multicastFlowControlSupplier) { multicastFlowControlSupplier = Configuration.multicastFlowControlSupplier(); } if (null == sendChannelEndpointSupplier) { sendChannelEndpointSupplier = Configuration.sendChannelEndpointSupplier(); } if (null == receiveChannelEndpointSupplier) { receiveChannelEndpointSupplier = Configuration.receiveChannelEndpointSupplier(); } if (null == dataTransportPoller) { dataTransportPoller = new DataTransportPoller(errorHandler); } if (null == controlTransportPoller) { controlTransportPoller = new ControlTransportPoller(errorHandler); } if (null == applicationSpecificFeedback) { applicationSpecificFeedback = Configuration.applicationSpecificFeedback(); } if (null == receiverGroupTag) { if (applicationSpecificFeedback.length > 0) { if (applicationSpecificFeedback.length != SIZE_OF_LONG) { throw new IllegalArgumentException( "applicationSpecificFeedback length must be equal to " + SIZE_OF_LONG + " bytes: length=" + applicationSpecificFeedback.length); } final UnsafeBuffer buffer = new UnsafeBuffer(applicationSpecificFeedback); receiverGroupTag = buffer.getLong(0, ByteOrder.LITTLE_ENDIAN); } } if (null == receiveChannelEndpointThreadLocals) { receiveChannelEndpointThreadLocals = new ReceiveChannelEndpointThreadLocals(); } if (null == congestionControlSupplier) { congestionControlSupplier = Configuration.congestionControlSupplier(); } if (null == driverCommandQueue) { driverCommandQueue = new ManyToOneConcurrentArrayQueue<>(CMD_QUEUE_CAPACITY); } if (null == receiverCommandQueue) { receiverCommandQueue = new OneToOneConcurrentArrayQueue<>(CMD_QUEUE_CAPACITY); } if (null == senderCommandQueue) { senderCommandQueue = new OneToOneConcurrentArrayQueue<>(CMD_QUEUE_CAPACITY); } if (null == retransmitUnicastDelayGenerator) { retransmitUnicastDelayGenerator = new StaticDelayGenerator(retransmitUnicastDelayNs, false); } if (null == retransmitUnicastLingerGenerator) { retransmitUnicastLingerGenerator = new StaticDelayGenerator(retransmitUnicastLingerNs, false); } if (null == unicastFeedbackDelayGenerator) { unicastFeedbackDelayGenerator = new StaticDelayGenerator(nakUnicastDelayNs, true); } if (null == multicastFeedbackDelayGenerator) { multicastFeedbackDelayGenerator = new OptimalMulticastDelayGenerator( nakMulticastMaxBackoffNs, nakMulticastGroupSize); } if (null == threadingMode) { threadingMode = Configuration.threadingMode(); } if (null == terminationValidator) { terminationValidator = Configuration.terminationValidator(); } if (null == nameResolver) { nameResolver = DefaultNameResolver.INSTANCE; } if (null == channelReceiveTimestampClock) { channelReceiveTimestampClock = new SystemEpochNanoClock(); } if (null == channelSendTimestampClock) { channelSendTimestampClock = new SystemEpochNanoClock(); } } private void concludeDependantProperties() { clientProxy = new ClientProxy(new BroadcastTransmitter( createToClientsBuffer(cncByteBuffer, cncMetaDataBuffer))); toDriverCommands = new ManyToOneRingBuffer(createToDriverBuffer(cncByteBuffer, cncMetaDataBuffer)); if (null == errorLog) { errorLog = new DistinctErrorLog( createErrorLogBuffer(cncByteBuffer, cncMetaDataBuffer), epochClock, US_ASCII); } errorHandler = CommonContext.setupErrorHandler(this.errorHandler, errorLog); receiverProxy = new ReceiverProxy( threadingMode, receiverCommandQueue, systemCounters.get(RECEIVER_PROXY_FAILS)); senderProxy = new SenderProxy( threadingMode, senderCommandQueue, systemCounters.get(SENDER_PROXY_FAILS)); driverConductorProxy = new DriverConductorProxy( threadingMode, driverCommandQueue, systemCounters.get(CONDUCTOR_PROXY_FAILS)); if (null == logFactory) { logFactory = new FileStoreLogFactory( aeronDirectoryName(), filePageSize, performStorageChecks, lowStorageWarningThreshold, errorHandler); } if (null == lossReport) { final long pageAlignedLossReportBufferLength = BitUtil.align(lossReportBufferLength, filePageSize); validateValueRange( pageAlignedLossReportBufferLength, LOSS_REPORT_BUFFER_LENGTH_DEFAULT, Integer.MAX_VALUE, "lossReportBufferLength"); lossReportBuffer = mapLossReport( aeronDirectoryName(), (int)pageAlignedLossReportBufferLength); lossReport = new LossReport(new UnsafeBuffer(lossReportBuffer)); } if (null == conductorDutyCycleTracker) { conductorDutyCycleTracker = new DutyCycleStallTracker( systemCounters.get(CONDUCTOR_MAX_CYCLE_TIME), systemCounters.get(CONDUCTOR_CYCLE_TIME_THRESHOLD_EXCEEDED), conductorCycleThresholdNs); } if (null == senderDutyCycleTracker) { senderDutyCycleTracker = new DutyCycleStallTracker( systemCounters.get(SENDER_MAX_CYCLE_TIME), systemCounters.get(SENDER_CYCLE_TIME_THRESHOLD_EXCEEDED), senderCycleThresholdNs); } if (null == receiverDutyCycleTracker) { receiverDutyCycleTracker = new DutyCycleStallTracker( systemCounters.get(RECEIVER_MAX_CYCLE_TIME), systemCounters.get(RECEIVER_CYCLE_TIME_THRESHOLD_EXCEEDED), receiverCycleThresholdNs); } if (null == nameResolverTimeTracker) { nameResolverTimeTracker = new DutyCycleStallTracker( systemCounters.get(NAME_RESOLVER_MAX_TIME), systemCounters.get(NAME_RESOLVER_TIME_THRESHOLD_EXCEEDED), nameResolverThresholdNs); } if (null == senderPortManager) { senderPortManager = new WildcardPortManager( WildcardPortManager.parsePortRange(senderWildcardPortRange), true); } if (null == receiverPortManager) { receiverPortManager = new WildcardPortManager( WildcardPortManager.parsePortRange(receiverWildcardPortRange), false); } nameResolver.init(countersManager, countersManager::newCounter); } private void concludeCounters() { if (null == countersManager) { if (countersMetaDataBuffer() == null) { countersMetaDataBuffer(createCountersMetaDataBuffer(cncByteBuffer, cncMetaDataBuffer)); } if (countersValuesBuffer() == null) { countersValuesBuffer(createCountersValuesBuffer(cncByteBuffer, cncMetaDataBuffer)); } final long reuseTimeoutMs = counterFreeToReuseTimeoutNs > 0 ? Math.max(TimeUnit.NANOSECONDS.toMillis(counterFreeToReuseTimeoutNs), 1) : 0; countersManager = useConcurrentCountersManager ? new ConcurrentCountersManager( countersMetaDataBuffer(), countersValuesBuffer(), US_ASCII, cachedEpochClock, reuseTimeoutMs) : new CountersManager( countersMetaDataBuffer(), countersValuesBuffer(), US_ASCII, cachedEpochClock, reuseTimeoutMs); } if (null == systemCounters) { systemCounters = new SystemCounters(countersManager); } } private void concludeIdleStrategies() { final StatusIndicator indicator = new UnsafeBufferStatusIndicator( countersManager.valuesBuffer(), CONTROLLABLE_IDLE_STRATEGY.id()); switch (threadingMode) { case INVOKER: break; case SHARED: if (null == sharedThreadFactory) { sharedThreadFactory = Thread::new; } if (null == sharedIdleStrategy) { sharedIdleStrategy = Configuration.sharedIdleStrategy(indicator); } break; case SHARED_NETWORK: if (null == conductorThreadFactory) { conductorThreadFactory = Thread::new; } if (null == conductorIdleStrategy) { conductorIdleStrategy = Configuration.conductorIdleStrategy(indicator); } if (null == sharedNetworkThreadFactory) { sharedNetworkThreadFactory = Thread::new; } if (null == sharedNetworkIdleStrategy) { sharedNetworkIdleStrategy = Configuration.sharedNetworkIdleStrategy(indicator); } break; case DEDICATED: if (null == conductorThreadFactory) { conductorThreadFactory = Thread::new; } if (null == senderThreadFactory) { senderThreadFactory = Thread::new; } if (null == receiverThreadFactory) { receiverThreadFactory = Thread::new; } if (null == conductorIdleStrategy) { conductorIdleStrategy = Configuration.conductorIdleStrategy(indicator); } if (null == senderIdleStrategy) { senderIdleStrategy = Configuration.senderIdleStrategy(indicator); } if (null == receiverIdleStrategy) { receiverIdleStrategy = Configuration.receiverIdleStrategy(indicator); } break; } } /** * {@inheritDoc} */ @SuppressWarnings("MethodLength") public String toString() { return "MediaDriver.Context" + "\n{" + "\n isConcluded=" + isConcluded() + "\n isClosed=" + (1 == isClosed) + "\n cncVersion=" + SemanticVersion.toString(CNC_VERSION) + "\n aeronDirectory=" + aeronDirectory() + "\n aeronDirectoryName='" + aeronDirectoryName() + '\'' + "\n cncFile=" + cncFile() + "\n countersMetaDataBuffer=" + countersMetaDataBuffer() + "\n countersValuesBuffer=" + countersValuesBuffer() + "\n driverTimeoutMs=" + driverTimeoutMs() + "\n printConfigurationOnStart=" + printConfigurationOnStart + "\n useWindowsHighResTimer=" + useWindowsHighResTimer + "\n warnIfDirectoryExists=" + warnIfDirectoryExists + "\n dirDeleteOnStart=" + dirDeleteOnStart + "\n dirDeleteOnShutdown=" + dirDeleteOnShutdown + "\n termBufferSparseFile=" + termBufferSparseFile + "\n performStorageChecks=" + performStorageChecks + "\n spiesSimulateConnection=" + spiesSimulateConnection + "\n reliableStream=" + reliableStream + "\n tetherSubscriptions=" + tetherSubscriptions + "\n rejoinStream=" + rejoinStream + "\n receiverGroupConsideration=" + receiverGroupConsideration + "\n conductorBufferLength=" + conductorBufferLength + "\n toClientsBufferLength=" + toClientsBufferLength + "\n counterValuesBufferLength=" + counterValuesBufferLength + "\n errorBufferLength=" + errorBufferLength + "\n lowStorageWarningThreshold=" + lowStorageWarningThreshold + "\n timerIntervalNs=" + timerIntervalNs + "\n clientLivenessTimeoutNs=" + clientLivenessTimeoutNs + "\n imageLivenessTimeoutNs=" + imageLivenessTimeoutNs + "\n publicationUnblockTimeoutNs=" + publicationUnblockTimeoutNs + "\n publicationConnectionTimeoutNs=" + publicationConnectionTimeoutNs + "\n publicationLingerTimeoutNs=" + publicationLingerTimeoutNs + "\n untetheredWindowLimitTimeoutNs=" + untetheredWindowLimitTimeoutNs + "\n untetheredRestingTimeoutNs=" + untetheredRestingTimeoutNs + "\n retransmitUnicastDelayNs=" + retransmitUnicastDelayNs + "\n retransmitUnicastLingerNs=" + retransmitUnicastLingerNs + "\n nakUnicastDelayNs=" + nakUnicastDelayNs + "\n nakMulticastMaxBackoffNs=" + nakMulticastMaxBackoffNs + "\n nakMulticastGroupSize=" + nakMulticastGroupSize + "\n statusMessageTimeoutNs=" + statusMessageTimeoutNs + "\n counterFreeToReuseTimeoutNs=" + counterFreeToReuseTimeoutNs + "\n conductorCycleThresholdNs=" + conductorCycleThresholdNs + "\n senderCycleThresholdNs=" + senderCycleThresholdNs + "\n receiverCycleThresholdNs=" + receiverCycleThresholdNs + "\n nameResolverThresholdNs=" + nameResolverThresholdNs + "\n publicationTermBufferLength=" + publicationTermBufferLength + "\n ipcTermBufferLength=" + ipcTermBufferLength + "\n publicationTermWindowLength=" + publicationTermWindowLength + "\n ipcPublicationTermWindowLength=" + ipcPublicationTermWindowLength + "\n initialWindowLength=" + initialWindowLength + "\n socketSndbufLength=" + socketSndbufLength + "\n socketRcvbufLength=" + socketRcvbufLength + "\n socketMulticastTtl=" + socketMulticastTtl + "\n mtuLength=" + mtuLength + "\n ipcMtuLength=" + ipcMtuLength + "\n filePageSize=" + filePageSize + "\n publicationReservedSessionIdLow=" + publicationReservedSessionIdLow + "\n publicationReservedSessionIdHigh=" + publicationReservedSessionIdHigh + "\n lossReportBufferLength=" + lossReportBufferLength + "\n epochClock=" + epochClock + "\n nanoClock=" + nanoClock + "\n cachedEpochClock=" + cachedEpochClock + "\n cachedNanoClock=" + cachedNanoClock + "\n threadingMode=" + threadingMode + "\n conductorThreadFactory=" + conductorThreadFactory + "\n senderThreadFactory=" + senderThreadFactory + "\n receiverThreadFactory=" + receiverThreadFactory + "\n sharedThreadFactory=" + sharedThreadFactory + "\n sharedNetworkThreadFactory=" + sharedNetworkThreadFactory + "\n conductorIdleStrategy=" + conductorIdleStrategy + "\n senderIdleStrategy=" + senderIdleStrategy + "\n receiverIdleStrategy=" + receiverIdleStrategy + "\n sharedNetworkIdleStrategy=" + sharedNetworkIdleStrategy + "\n sharedIdleStrategy=" + sharedIdleStrategy + "\n sendChannelEndpointSupplier=" + sendChannelEndpointSupplier + "\n receiveChannelEndpointSupplier=" + receiveChannelEndpointSupplier + "\n receiveChannelEndpointThreadLocals=" + receiveChannelEndpointThreadLocals + "\n tempBuffer=" + tempBuffer + "\n unicastFlowControlSupplier=" + unicastFlowControlSupplier + "\n multicastFlowControlSupplier=" + multicastFlowControlSupplier + "\n applicationSpecificFeedback=" + Arrays.toString(applicationSpecificFeedback) + "\n receiverGroupTag=" + receiverGroupTag + "\n flowControlGroupTag=" + flowControlGroupTag + "\n flowControlGroupMinSize=" + flowControlGroupMinSize + "\n flowControlReceiverTimeoutNs=" + flowControlReceiverTimeoutNs + "\n reResolutionCheckIntervalNs=" + reResolutionCheckIntervalNs + "\n receiverGroupConsideration=" + receiverGroupConsideration + "\n congestionControlSupplier=" + congestionControlSupplier + "\n terminationValidator=" + terminationValidator + "\n terminationHook=" + terminationHook + "\n nameResolver=" + nameResolver + "\n resolverName='" + resolverName + '\'' + "\n resolverInterface='" + resolverInterface + '\'' + "\n resolverBootstrapNeighbor='" + resolverBootstrapNeighbor + '\'' + "\n sendToStatusMessagePollRatio=" + sendToStatusMessagePollRatio + "\n unicastFeedbackDelayGenerator=" + unicastFeedbackDelayGenerator + "\n multicastFeedbackDelayGenerator=" + multicastFeedbackDelayGenerator + "\n retransmitUnicastDelayGenerator=" + retransmitUnicastDelayGenerator + "\n retransmitUnicastLingerGenerator=" + retransmitUnicastLingerGenerator + "\n errorLog=" + errorLog + "\n errorHandler=" + errorHandler + "\n useConcurrentCountersManager=" + useConcurrentCountersManager + "\n countersManager=" + countersManager + "\n systemCounters=" + systemCounters + "\n lossReport=" + lossReport + "\n logFactory=" + logFactory + "\n dataTransportPoller=" + dataTransportPoller + "\n controlTransportPoller=" + controlTransportPoller + "\n driverCommandQueue=" + driverCommandQueue + "\n receiverCommandQueue=" + receiverCommandQueue + "\n senderCommandQueue=" + senderCommandQueue + "\n receiverProxy=" + receiverProxy + "\n senderProxy=" + senderProxy + "\n driverConductorProxy=" + driverConductorProxy + "\n clientProxy=" + clientProxy + "\n toDriverCommands=" + toDriverCommands + "\n lossReportBuffer=" + lossReportBuffer + "\n cncByteBuffer=" + cncByteBuffer + "\n cncMetaDataBuffer=" + cncMetaDataBuffer + "\n channelSendTimestampClock=" + channelSendTimestampClock + "\n channelReceiveTimestampClock=" + channelReceiveTimestampClock + "\n conductorDutyCycleTracker=" + conductorDutyCycleTracker + "\n senderDutyCycleTracker=" + senderDutyCycleTracker + "\n receiverDutyCycleTracker=" + receiverDutyCycleTracker + "\n senderWildcardPortRange=" + senderWildcardPortRange + "\n receiverWildcardPortRange=" + receiverWildcardPortRange + "\n senderPortManager=" + senderPortManager + "\n receiverPortManager=" + receiverPortManager + "\n resourceFreeLimit=" + resourceFreeLimit + "\n}"; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy