Example #1
0
        internal ClientConductor(
            IEpochClock epochClock,
            INanoClock nanoClock,
            CopyBroadcastReceiver broadcastReceiver,
            ILogBuffersFactory logBuffersFactory,
            UnsafeBuffer counterValuesBuffer,
            DriverProxy driverProxy,
            ErrorHandler errorHandler,
            AvailableImageHandler availableImageHandler,
            UnavailableImageHandler unavailableImageHandler,
            long keepAliveIntervalNs,
            long driverTimeoutMs,
            long interServiceTimeoutNs,
            long publicationConnectionTimeoutMs)
        {
            _epochClock                     = epochClock;
            _nanoClock                      = nanoClock;
            _timeOfLastKeepalive            = nanoClock.NanoTime();
            _timeOfLastCheckResources       = nanoClock.NanoTime();
            _timeOfLastWork                 = nanoClock.NanoTime();
            _errorHandler                   = errorHandler;
            _counterValuesBuffer            = counterValuesBuffer;
            _driverProxy                    = driverProxy;
            _logBuffersFactory              = logBuffersFactory;
            _availableImageHandler          = availableImageHandler;
            _unavailableImageHandler        = unavailableImageHandler;
            _keepAliveIntervalNs            = keepAliveIntervalNs;
            _driverTimeoutMs                = driverTimeoutMs;
            _driverTimeoutNs                = NanoUtil.FromMilliseconds(driverTimeoutMs);
            _interServiceTimeoutNs          = interServiceTimeoutNs;
            _publicationConnectionTimeoutMs = publicationConnectionTimeoutMs;

            _driverListener = new DriverListenerAdapter(broadcastReceiver, this);
        }
Example #2
0
        internal ClientConductor(Aeron.Context ctx)
        {
            _ctx = ctx;

            _clientLock                     = ctx.ClientLock();
            _epochClock                     = ctx.EpochClock();
            _nanoClock                      = ctx.NanoClock();
            _errorHandler                   = ctx.ErrorHandler();
            _counterValuesBuffer            = ctx.CountersValuesBuffer();
            _driverProxy                    = ctx.DriverProxy();
            _logBuffersFactory              = ctx.LogBuffersFactory();
            _imageMapMode                   = ctx.ImageMapMode();
            _keepAliveIntervalNs            = ctx.KeepAliveInterval();
            _driverTimeoutMs                = ctx.DriverTimeoutMs();
            _driverTimeoutNs                = _driverTimeoutMs * 1000000;
            _interServiceTimeoutNs          = ctx.InterServiceTimeout();
            _publicationConnectionTimeoutMs = ctx.PublicationConnectionTimeout();
            _driverListener                 = new DriverListenerAdapter(ctx.ToClientBuffer(), this);
            _driverAgentInvoker             = ctx.DriverAgentInvoker();

            long nowNs = _nanoClock.NanoTime();

            _timeOfLastKeepaliveNs      = nowNs;
            _timeOfLastCheckResourcesNs = nowNs;
            _timeOfLastWorkNs           = nowNs;
        }
        internal ClusteredServiceAgent(ClusteredServiceContainer.Context ctx)
        {
            this.ctx = ctx;

            archiveCtx   = ctx.ArchiveContext();
            aeron        = ctx.Aeron();
            service      = ctx.ClusteredService();
            idleStrategy = ctx.IdleStrategy();
            serviceId    = ctx.ServiceId();
            epochClock   = ctx.EpochClock();
            markFile     = ctx.MarkFile();


            var channel = ctx.ServiceControlChannel();

            _consensusModuleProxy = new ConsensusModuleProxy(aeron.AddPublication(channel, ctx.ConsensusModuleStreamId()));
            _serviceAdapter       = new ServiceAdapter(aeron.AddSubscription(channel, ctx.ServiceStreamId()), this);

            UnsafeBuffer headerBuffer = new UnsafeBuffer(new byte[SESSION_HEADER_LENGTH]);

            _egressMessageHeaderEncoder.WrapAndApplyHeader(headerBuffer, 0, new MessageHeaderEncoder());

            _vectors[0] = new DirectBufferVector(headerBuffer, 0, SESSION_HEADER_LENGTH);
            _vectors[1] = _messageVector;
        }
Example #4
0
        internal ClientConductor(Aeron.Context ctx)
        {
            _ctx = ctx;

            _clientLock = ctx.ClientLock();
            _epochClock = ctx.EpochClock();
            _nanoClock  = ctx.NanoClock();

            _driverProxy       = ctx.DriverProxy();
            _logBuffersFactory = ctx.LogBuffersFactory();

            _keepAliveIntervalNs            = ctx.KeepAliveInterval();
            _driverTimeoutMs                = ctx.DriverTimeoutMs();
            _driverTimeoutNs                = _driverTimeoutMs * 1000000;
            _interServiceTimeoutNs          = ctx.InterServiceTimeout();
            _defaultAvailableImageHandler   = ctx.AvailableImageHandler();
            _defaultUnavailableImageHandler = ctx.UnavailableImageHandler();
            _availableCounterHandler        = ctx.AvailableCounterHandler();
            _unavailableCounterHandler      = ctx.UnavailableCounterHandler();
            _driverEventsAdapter            = new DriverEventsAdapter(ctx.ToClientBuffer(), this);
            _counterValuesBuffer            = ctx.CountersValuesBuffer();
            _countersReader =
                new CountersReader(ctx.CountersMetaDataBuffer(), ctx.CountersValuesBuffer(), Encoding.ASCII);

            long nowNs = _nanoClock.NanoTime();

            _timeOfLastKeepAliveNs      = nowNs;
            _timeOfLastResourcesCheckNs = nowNs;
            _timeOfLastServiceNs        = nowNs;
        }
Example #5
0
        internal ClientConductor(Aeron.Context ctx)
        {
            _clientLock                     = ctx.ClientLock();
            _epochClock                     = ctx.EpochClock();
            _nanoClock                      = ctx.NanoClock();
            _errorHandler                   = ctx.ErrorHandler();
            _counterValuesBuffer            = ctx.CountersValuesBuffer();
            _driverProxy                    = ctx.DriverProxy();
            _logBuffersFactory              = ctx.LogBuffersFactory();
            _imageMapMode                   = ctx.ImageMapMode();
            _keepAliveIntervalNs            = ctx.KeepAliveInterval();
            _driverTimeoutMs                = ctx.DriverTimeoutMs();
            _driverTimeoutNs                = _driverTimeoutMs * 1000000;
            _interServiceTimeoutNs          = ctx.InterServiceTimeout();
            _publicationConnectionTimeoutMs = ctx.PublicationConnectionTimeout();
            _defaultAvailableImageHandler   = ctx.AvailableImageHandler();
            _defaultUnavailableImageHandler = ctx.UnavailableImageHandler();
            _driverEventsAdapter            = new DriverEventsAdapter(ctx.ToClientBuffer(), this);

            long nowNs = _nanoClock.NanoTime();

            _timeOfLastKeepAliveNs      = nowNs;
            _timeOfLastResourcesCheckNs = nowNs;
            _timeOfLastServiceNs        = nowNs;
        }
Example #6
0
        public ClusterMarkFile(
            FileInfo file,
            ClusterComponentType type,
            int errorBufferLength,
            IEpochClock epochClock,
            long timeoutMs)
        {
            var markFileExists = file.Exists;

            markFile = new MarkFile(
                file,
                markFileExists,
                MarkFileHeaderDecoder.VersionEncodingOffset(),
                MarkFileHeaderDecoder.ActivityTimestampEncodingOffset(),
                HEADER_LENGTH + errorBufferLength,
                timeoutMs,
                epochClock,
                (version) =>
            {
                if (version != MarkFileHeaderDecoder.SCHEMA_VERSION)
                {
                    throw new ClusterException("mark file version " + version + " does not match software:" + MarkFileHeaderDecoder.SCHEMA_VERSION);
                }
            },
                null);

            buffer      = markFile.Buffer();
            errorBuffer = new UnsafeBuffer(buffer, HEADER_LENGTH, errorBufferLength);


            headerEncoder.Wrap(buffer, 0);
            headerDecoder.Wrap(buffer, 0, MarkFileHeaderDecoder.BLOCK_LENGTH, MarkFileHeaderDecoder.SCHEMA_VERSION);

            if (markFileExists)
            {
                var existingErrorBuffer = new UnsafeBuffer(
                    buffer, headerDecoder.HeaderLength(), headerDecoder.ErrorBufferLength());

                SaveExistingErrors(file, existingErrorBuffer, Console.Error);

                errorBuffer.SetMemory(0, errorBufferLength, 0);
            }
            else
            {
                headerEncoder.CandidateTermId(Aeron.Aeron.NULL_VALUE);
            }

            var existingType = headerDecoder.ComponentType();

            if (existingType != ClusterComponentType.NULL && existingType != type)
            {
                throw new InvalidOperationException("existing Mark file type " + existingType + " not same as required type " + type);
            }

            headerEncoder.ComponentType(type);
            headerEncoder.HeaderLength(HEADER_LENGTH);
            headerEncoder.ErrorBufferLength(errorBufferLength);
            headerEncoder.Pid(Process.GetCurrentProcess().Id);
            headerEncoder.StartTimestamp(epochClock.Time());
        }
        internal ClusteredServiceAgent(ClusteredServiceContainer.Context ctx)
        {
            this.ctx = ctx;

            headerVector = new DirectBufferVector(headerBuffer, 0, headerBuffer.Capacity);

            abortHandler      = Abort;
            archiveCtx        = ctx.ArchiveContext();
            aeron             = ctx.Aeron();
            aeronAgentInvoker = ctx.Aeron().ConductorAgentInvoker;
            service           = ctx.ClusteredService();
            idleStrategy      = ctx.IdleStrategy();
            serviceId         = ctx.ServiceId();
            epochClock        = ctx.EpochClock();
            markFile          = ctx.MarkFile();


            var channel = ctx.ServiceControlChannel();

            _consensusModuleProxy =
                new ConsensusModuleProxy(aeron.AddPublication(channel, ctx.ConsensusModuleStreamId()));
            _serviceAdapter = new ServiceAdapter(aeron.AddSubscription(channel, ctx.ServiceStreamId()), this);
            _sessionMessageHeaderEncoder.WrapAndApplyHeader(headerBuffer, 0, new MessageHeaderEncoder());
            aeron.AddCloseHandler(abortHandler);
        }
Example #8
0
        /// <summary>
        /// Create a new counter buffer manager over two buffers.
        /// </summary>
        /// <param name="metaDataBuffer"> containing the types, keys, and labels for the counters. </param>
        /// <param name="valuesBuffer">   containing the values of the counters themselves. </param>
        public CountersManager(IAtomicBuffer metaDataBuffer, IAtomicBuffer valuesBuffer) : base(metaDataBuffer, valuesBuffer)
        {
            valuesBuffer.VerifyAlignment();
            _epochClock = new NullEpochClock();


            if (metaDataBuffer.Capacity < valuesBuffer.Capacity * 2)
            {
                throw new ArgumentException("Meta data buffer not sufficiently large");
            }
        }
Example #9
0
        /// <summary>
        /// Create a new counter buffer manager over two buffers.
        /// </summary>
        /// <param name="metaDataBuffer">       containing the types, keys, and labels for the counters. </param>
        /// <param name="valuesBuffer">         containing the values of the counters themselves. </param>
        /// <param name="labelCharset">         for the label encoding. </param>
        /// <param name="epochClock">           to use for determining time for keep counter from being reused after being freed. </param>
        /// <param name="freeToReuseTimeoutMs"> timeout (in milliseconds) to keep counter from being reused after being freed. </param>
        public CountersManager(IAtomicBuffer metaDataBuffer, IAtomicBuffer valuesBuffer, Encoding labelCharset, IEpochClock epochClock, long freeToReuseTimeoutMs) : base(metaDataBuffer, valuesBuffer, labelCharset)
        {
            valuesBuffer.VerifyAlignment();
            _epochClock           = epochClock;
            _freeToReuseTimeoutMs = freeToReuseTimeoutMs;

            if (metaDataBuffer.Capacity < (valuesBuffer.Capacity * 2))
            {
                throw new ArgumentException("Meta data buffer not sufficiently large");
            }
        }
Example #10
0
        /// <summary>
        /// Map a pre-existing CnC file if one present and is active.
        ///
        /// Total length of CnC file will be mapped until <seealso cref="#close()"/> is called.
        /// </summary>
        /// <param name="directory">             for the CnC file </param>
        /// <param name="filename">              of the CnC file </param>
        /// <param name="versionFieldOffset">    to use for version field access </param>
        /// <param name="timestampFieldOffset">  to use for timestamp field access </param>
        /// <param name="timeoutMs">             for the activity check (in milliseconds) and for how long to wait for file to exist </param>
        /// <param name="epochClock">            to use for time checks </param>
        /// <param name="versionCheck">          to use for existing CnC file and version field </param>
        /// <param name="logger">                to use to signal progress or null </param>
        public MarkFile(DirectoryInfo directory, string filename, int versionFieldOffset, int timestampFieldOffset,
                        long timeoutMs, IEpochClock epochClock, Action <int> versionCheck, Action <string> logger)
        {
            ValidateOffsets(versionFieldOffset, timestampFieldOffset);

            this.parentDir    = directory;
            this.markFile     = new FileInfo(Path.Combine(directory.FullName, filename));
            this.mappedBuffer = MapExistingCncFile(markFile, versionFieldOffset, timestampFieldOffset, timeoutMs,
                                                   epochClock, versionCheck, logger);
            this.buffer               = new UnsafeBuffer(mappedBuffer);
            this.versionFieldOffset   = versionFieldOffset;
            this.timestampFieldOffset = timestampFieldOffset;
        }
Example #11
0
        public ClusterMarkFile(DirectoryInfo directory, string filename, IEpochClock epochClock, long timeoutMs, Action <string> logger)
        {
            markFile = new MarkFile(directory, filename, MarkFileHeaderDecoder.VersionEncodingOffset(), MarkFileHeaderDecoder.ActivityTimestampEncodingOffset(), timeoutMs, epochClock, (version) =>
            {
                if (version != MarkFileHeaderDecoder.SCHEMA_VERSION)
                {
                    throw new ArgumentException("Mark file version " + version + " does not match software:" + MarkFileHeaderDecoder.SCHEMA_VERSION);
                }
            }, logger);

            buffer = markFile.Buffer();
            headerDecoder.Wrap(buffer, 0, MarkFileHeaderDecoder.BLOCK_LENGTH, MarkFileHeaderDecoder.SCHEMA_VERSION);
        }
Example #12
0
        public static MappedByteBuffer MapNewOrExistingCncFile(FileInfo cncFile, bool shouldPreExist,
                                                               int versionFieldOffset, int timestampFieldOffset, long totalFileLength, long timeoutMs,
                                                               IEpochClock epochClock, Action <int> versionCheck, Action <string> logger)
        {
            MappedByteBuffer cncByteBuffer = null;

            try
            {
                cncByteBuffer = IoUtil.MapNewOrExixtingFile(cncFile, totalFileLength);

                UnsafeBuffer cncBuffer = new UnsafeBuffer(cncByteBuffer);

                if (shouldPreExist)
                {
                    int cncVersion = cncBuffer.GetIntVolatile(versionFieldOffset);

                    if (null != logger)
                    {
                        logger("INFO: CnC file exists: " + cncFile);
                    }

                    versionCheck(cncVersion);

                    long timestamp    = cncBuffer.GetLongVolatile(timestampFieldOffset);
                    long now          = epochClock.Time();
                    long timestampAge = now - timestamp;

                    if (null != logger)
                    {
                        logger("INFO: heartbeat is (ms): " + timestampAge);
                    }

                    if (timestampAge < timeoutMs)
                    {
                        throw new System.InvalidOperationException("Active CnC file detected");
                    }
                }
            }
            catch (Exception)
            {
                if (null != cncByteBuffer)
                {
                    IoUtil.Unmap(cncByteBuffer);
                }

                throw;
            }

            return(cncByteBuffer);
        }
Example #13
0
        /// <summary>
        /// Create a CnC file if none present. Checking if an active CnC file exists and is active. Existing CnC file
        /// is used if not active.
        ///
        /// Total length of CnC file will be mapped until <seealso cref="#close()"/> is called.
        /// </summary>
        /// <param name="markFile">               to use </param>
        /// <param name="shouldPreExist">        or not </param>
        /// <param name="versionFieldOffset">    to use for version field access </param>
        /// <param name="timestampFieldOffset">  to use for timestamp field access </param>
        /// <param name="totalFileLength">       to allocate when creating new CnC file </param>
        /// <param name="timeoutMs">             for the activity check (in milliseconds) </param>
        /// <param name="epochClock">            to use for time checks </param>
        /// <param name="versionCheck">          to use for existing CnC file and version field </param>
        /// <param name="logger">                to use to signal progress or null </param>
        public MarkFile(FileInfo markFile, bool shouldPreExist, int versionFieldOffset, int timestampFieldOffset,
                        int totalFileLength, long timeoutMs, IEpochClock epochClock, Action <int> versionCheck,
                        Action <string> logger)
        {
            ValidateOffsets(versionFieldOffset, timestampFieldOffset);

            this.parentDir    = markFile.Directory;
            this.markFile     = markFile;
            this.mappedBuffer = MapNewOrExistingCncFile(markFile, shouldPreExist, versionFieldOffset,
                                                        timestampFieldOffset, totalFileLength, timeoutMs, epochClock, versionCheck, logger);

            this.buffer               = new UnsafeBuffer(mappedBuffer.Pointer, totalFileLength);
            this.versionFieldOffset   = versionFieldOffset;
            this.timestampFieldOffset = timestampFieldOffset;
        }
Example #14
0
        /// <summary>
        /// Create a CnC directory and file if none present. Checking if an active CnC file exists and is active. Old CnC
        /// file is deleted and recreated if not active.
        ///
        /// Total length of CnC file will be mapped until <seealso cref="#close()"/> is called.
        /// </summary>
        /// <param name="directory">             for the CnC file </param>
        /// <param name="filename">              of the CnC file </param>
        /// <param name="warnIfDirectoryExists"> for logging purposes </param>
        /// <param name="dirDeleteOnStart">      if desired </param>
        /// <param name="versionFieldOffset">    to use for version field access </param>
        /// <param name="timestampFieldOffset">  to use for timestamp field access </param>
        /// <param name="totalFileLength">       to allocate when creating new CnC file </param>
        /// <param name="timeoutMs">             for the activity check (in milliseconds) </param>
        /// <param name="epochClock">            to use for time checks </param>
        /// <param name="versionCheck">          to use for existing CnC file and version field </param>
        /// <param name="logger">                to use to signal progress or null </param>
        public MarkFile(DirectoryInfo directory, string filename, bool warnIfDirectoryExists, bool dirDeleteOnStart,
                        int versionFieldOffset, int timestampFieldOffset, int totalFileLength, long timeoutMs,
                        IEpochClock epochClock, Action <int> versionCheck, Action <string> logger)
        {
            ValidateOffsets(versionFieldOffset, timestampFieldOffset);

            EnsureDirectoryExists(directory, filename, warnIfDirectoryExists, dirDeleteOnStart, versionFieldOffset,
                                  timestampFieldOffset, timeoutMs, epochClock, versionCheck, logger);

            this.parentDir            = directory;
            this.markFile             = new FileInfo(Path.Combine(directory.Name, filename));
            this.mappedBuffer         = MapNewFile(markFile, totalFileLength);
            this.buffer               = new UnsafeBuffer(mappedBuffer.Pointer, totalFileLength);
            this.versionFieldOffset   = versionFieldOffset;
            this.timestampFieldOffset = timestampFieldOffset;
        }
Example #15
0
        internal ClusteredServiceAgent(ClusteredServiceContainer.Context ctx)
        {
            this.ctx = ctx;

            archiveCtx   = ctx.ArchiveContext();
            aeron        = ctx.Aeron();
            service      = ctx.ClusteredService();
            idleStrategy = ctx.IdleStrategy();
            serviceId    = ctx.ServiceId();
            epochClock   = ctx.EpochClock();
            markFile     = ctx.MarkFile();


            var channel = ctx.ServiceControlChannel();

            _consensusModuleProxy = new ConsensusModuleProxy(aeron.AddPublication(channel, ctx.ConsensusModuleStreamId()));
            _serviceAdapter       = new ServiceAdapter(aeron.AddSubscription(channel, ctx.ServiceStreamId()), this);
        }
Example #16
0
        internal ClientConductor(Aeron.Context ctx, Aeron aeron)
        {
            _ctx   = ctx;
            _aeron = aeron;

            _clientLock                     = ctx.ClientLock();
            _epochClock                     = ctx.EpochClock();
            _nanoClock                      = ctx.NanoClock();
            _awaitingIdleStrategy           = ctx.AwaitingIdleStrategy();
            _driverProxy                    = ctx.DriverProxy();
            _logBuffersFactory              = ctx.LogBuffersFactory();
            _keepAliveIntervalNs            = ctx.KeepAliveIntervalNs();
            _driverTimeoutMs                = ctx.DriverTimeoutMs();
            _driverTimeoutNs                = _driverTimeoutMs * 1000000;
            _interServiceTimeoutNs          = ctx.InterServiceTimeoutNs();
            _defaultAvailableImageHandler   = ctx.AvailableImageHandler();
            _defaultUnavailableImageHandler = ctx.UnavailableImageHandler();
            _driverEventsAdapter            =
                new DriverEventsAdapter(ctx.ToClientBuffer(), ctx.ClientId(), this, _asyncCommandIdSet);
            _driverAgentInvoker  = ctx.DriverAgentInvoker();
            _counterValuesBuffer = ctx.CountersValuesBuffer();
            _countersReader      =
                new CountersReader(ctx.CountersMetaDataBuffer(), ctx.CountersValuesBuffer(), Encoding.ASCII);

            if (null != ctx.AvailableCounterHandler())
            {
                _availableCounterHandlers.Add(ctx.AvailableCounterHandler());
            }

            if (null != ctx.UnavailableCounterHandler())
            {
                _unavailableCounterHandlers.Add(ctx.UnavailableCounterHandler());
            }

            if (null != ctx.CloseHandler())
            {
                _closeHandlers.Add(ctx.CloseHandler());
            }

            long nowNs = _nanoClock.NanoTime();

            _timeOfLastKeepAliveNs = nowNs;
            _timeOfLastServiceNs   = nowNs;
        }
Example #17
0
        internal ClusteredServiceAgent(ClusteredServiceContainer.Context ctx)
        {
            this.ctx = ctx;

            archiveCtx           = ctx.ArchiveContext();
            aeron                = ctx.Aeron();
            shouldCloseResources = ctx.OwnsAeronClient();
            service              = ctx.ClusteredService();
            recordingLog         = ctx.RecordingLog();
            idleStrategy         = ctx.IdleStrategy();
            serviceId            = ctx.ServiceId();
            epochClock           = ctx.EpochClock();
            markFile             = ctx.MarkFile();


            var channel  = ctx.ServiceControlChannel();
            var streamId = ctx.ServiceControlStreamId();

            serviceControlPublisher = new ServiceControlPublisher(aeron.AddPublication(channel, streamId));
            serviceControlAdapter   = new ServiceControlAdapter(aeron.AddSubscription(channel, streamId), this);
        }
Example #18
0
        public static void EnsureDirectoryExists(DirectoryInfo directory, string filename, bool warnIfDirectoryExists,
                                                 bool dirDeleteOnStart, int versionFieldOffset, int timestampFieldOffset, long timeoutMs,
                                                 IEpochClock epochClock, Action <int> versionCheck, Action <string> logger)
        {
            FileInfo cncFile = new FileInfo(Path.Combine(directory.FullName, filename));

            if (directory.Exists)
            {
                if (warnIfDirectoryExists && null != logger)
                {
                    logger("WARNING: " + directory + " already exists.");
                }

                if (!dirDeleteOnStart)
                {
                    int offset = Math.Min(versionFieldOffset, timestampFieldOffset);
                    int length = Math.Max(versionFieldOffset, timestampFieldOffset) + BitUtil.SIZE_OF_LONG - offset;
                    MappedByteBuffer cncByteBuffer = MapExistingFile(cncFile, logger, offset, length);

                    try
                    {
                        if (IsActive(cncByteBuffer, epochClock, timeoutMs, versionFieldOffset, timestampFieldOffset,
                                     versionCheck, logger))
                        {
                            throw new System.InvalidOperationException("Active CnC file detected");
                        }
                    }
                    finally
                    {
                        IoUtil.Unmap(cncByteBuffer);
                    }
                }

                IoUtil.Delete(directory, false);
            }

            IoUtil.EnsureDirectoryExists(directory, directory.ToString());
        }
Example #19
0
        public ClusterMarkFile(DirectoryInfo directory, string filename, IEpochClock epochClock, long timeoutMs,
                               Action <string> logger)
        {
            markFile = new MarkFile(
                directory,
                filename,
                MarkFileHeaderDecoder.VersionEncodingOffset(),
                MarkFileHeaderDecoder.ActivityTimestampEncodingOffset(),
                timeoutMs,
                epochClock,
                (version) =>
            {
                if (SemanticVersion.Major(version) != AeronCluster.Configuration.MAJOR_VERSION)
                {
                    throw new ArgumentException("mark file major version " + SemanticVersion.Major(version) +
                                                " does not match software:" + AeronCluster.Configuration.MAJOR_VERSION);
                }
            },
                logger);

            buffer = markFile.Buffer();
            headerDecoder.Wrap(buffer, 0, MarkFileHeaderDecoder.BLOCK_LENGTH, MarkFileHeaderDecoder.SCHEMA_VERSION);
            errorBuffer = new UnsafeBuffer(buffer, headerDecoder.HeaderLength(), headerDecoder.ErrorBufferLength());
        }
Example #20
0
        public static bool IsActive(MappedByteBuffer cncByteBuffer, IEpochClock epochClock, long timeoutMs,
                                    int versionFieldOffset, int timestampFieldOffset, Action <int> versionCheck, Action <string> logger)
        {
            if (null == cncByteBuffer)
            {
                return(false);
            }

            UnsafeBuffer cncBuffer = new UnsafeBuffer(cncByteBuffer);

            long startTimeMs = epochClock.Time();
            int  cncVersion;

            while (0 == (cncVersion = cncBuffer.GetIntVolatile(versionFieldOffset)))
            {
                if (epochClock.Time() > (startTimeMs + timeoutMs))
                {
                    throw new System.InvalidOperationException("CnC file is created but not initialised.");
                }

                Sleep(1);
            }

            versionCheck(cncVersion);

            long timestamp    = cncBuffer.GetLongVolatile(timestampFieldOffset);
            long now          = epochClock.Time();
            long timestampAge = now - timestamp;

            if (null != logger)
            {
                logger("INFO: heartbeat is (ms): " + timestampAge);
            }

            return(timestampAge <= timeoutMs);
        }
Example #21
0
    /// <summary>
    /// Create a <seealso cref="ReplayMerge"/> to manage the merging of a replayed stream and switching over to live stream as
    /// appropriate.
    /// </summary>
    /// <param name="subscription">           to use for the replay and live stream. Must be a multi-destination subscription. </param>
    /// <param name="archive">                to use for the replay. </param>
    /// <param name="replayChannel">          to use for the replay. </param>
    /// <param name="replayDestination">      to send the replay to and the destination added by the <seealso cref="Subscription"/>. </param>
    /// <param name="liveDestination">        for the live stream and the destination added by the <seealso cref="Subscription"/>. </param>
    /// <param name="recordingId">            for the replay. </param>
    /// <param name="startPosition">          for the replay. </param>
    /// <param name="epochClock">             to use for progress checks. </param>
    /// <param name="mergeProgressTimeoutMs"> to use for progress checks. </param>
    public ReplayMerge(Subscription subscription, AeronArchive archive, string replayChannel, string replayDestination,
                       string liveDestination, long recordingId, long startPosition, IEpochClock epochClock,
                       long mergeProgressTimeoutMs)
    {
        if (subscription.Channel.StartsWith(IPC_CHANNEL) || replayChannel.StartsWith(IPC_CHANNEL) ||
            replayDestination.StartsWith(IPC_CHANNEL) || liveDestination.StartsWith(IPC_CHANNEL))
        {
            throw new System.ArgumentException("IPC merging is not supported");
        }

        ChannelUri subscriptionChannelUri = ChannelUri.Parse(subscription.Channel);

        if (!MDC_CONTROL_MODE_MANUAL.Equals(subscriptionChannelUri.Get(MDC_CONTROL_MODE_PARAM_NAME)))
        {
            throw new ArgumentException("Subscription must have manual control-mode: control-mode=" +
                                        subscriptionChannelUri.Get(MDC_CONTROL_MODE_PARAM_NAME));
        }

        ChannelUri replayChannelUri = ChannelUri.Parse(replayChannel);

        replayChannelUri.Put(LINGER_PARAM_NAME, "0");
        replayChannelUri.Put(EOS_PARAM_NAME, "false");

        this.archive                = archive;
        this.subscription           = subscription;
        this.epochClock             = epochClock;
        this.replayDestination      = replayDestination;
        this.replayChannel          = replayChannelUri.ToString();
        this.liveDestination        = liveDestination;
        this.recordingId            = recordingId;
        this.startPosition          = startPosition;
        this.timeOfLastProgressMs   = epochClock.Time();
        this.mergeProgressTimeoutMs = mergeProgressTimeoutMs;

        subscription.AsyncAddDestination(replayDestination);
    }
Example #22
0
            /// <summary>
            /// This is called automatically by <seealso cref="Connect()"/> and its overloads.
            /// There is no need to call it from a client application. It is responsible for providing default
            /// values for options that are not individually changed through field setters.
            /// </summary>
            /// <returns> this Aeron.Context for method chaining. </returns>
            public Context Conclude()
            {
                try
                {
                    _cncFile = new FileInfo(Path.Combine(_aeronDirectoryName, CncFileDescriptor.CNC_FILE));

                    if (_epochClock == null)
                    {
                        _epochClock = new SystemEpochClock();
                    }

                    if (_nanoClock == null)
                    {
                        _nanoClock = new SystemNanoClock();
                    }

                    if (_idleStrategy == null)
                    {
                        _idleStrategy = new SleepingIdleStrategy(IdleSleepMs);
                    }

                    if (CncFile() != null)
                    {
                        _cncByteBuffer     = IoUtil.MapExistingFile(CncFile().FullName);
                        _cncMetaDataBuffer = CncFileDescriptor.CreateMetaDataBuffer(_cncByteBuffer);

                        var cncVersion = _cncMetaDataBuffer.GetInt(CncFileDescriptor.CncVersionOffset(0));

                        if (CncFileDescriptor.CNC_VERSION != cncVersion)
                        {
                            throw new InvalidOperationException(
                                      "aeron cnc file version not understood: version=" + cncVersion);
                        }
                    }

                    if (_toClientBuffer == null)
                    {
                        var receiver =
                            new BroadcastReceiver(CncFileDescriptor.CreateToClientsBuffer(_cncByteBuffer,
                                                                                          _cncMetaDataBuffer));
                        _toClientBuffer = new CopyBroadcastReceiver(receiver);
                    }

                    if (_toDriverBuffer == null)
                    {
                        _toDriverBuffer =
                            new ManyToOneRingBuffer(CncFileDescriptor.CreateToDriverBuffer(_cncByteBuffer,
                                                                                           _cncMetaDataBuffer));
                    }

                    if (CountersMetaDataBuffer() == null)
                    {
                        CountersMetaDataBuffer(CncFileDescriptor.CreateCountersMetaDataBuffer(_cncByteBuffer,
                                                                                              _cncMetaDataBuffer));
                    }

                    if (CountersValuesBuffer() == null)
                    {
                        CountersValuesBuffer(CncFileDescriptor.CreateCountersValuesBuffer(_cncByteBuffer,
                                                                                          _cncMetaDataBuffer));
                    }

                    _interServiceTimeout = CncFileDescriptor.ClientLivenessTimeout(_cncMetaDataBuffer);

                    if (_logBuffersFactory == null)
                    {
                        _logBuffersFactory = new MappedLogBuffersFactory();
                    }

                    if (_errorHandler == null)
                    {
                        _errorHandler = DEFAULT_ERROR_HANDLER;
                    }

                    if (_availableImageHandler == null)
                    {
                        _availableImageHandler = image => { };
                    }

                    if (_unavailableImageHandler == null)
                    {
                        _unavailableImageHandler = image => { };
                    }
                }
                catch (
                    Exception ex)
                {
                    Console.WriteLine("***");
                    Console.WriteLine("***");
                    Console.WriteLine("Failed to connect to the Media Driver - is it currently running?");
                    Console.WriteLine("***");
                    Console.WriteLine("***");

                    throw new InvalidOperationException("Could not initialise communication buffers", ex);
                }

                return(this);
            }
Example #23
0
        public ClusterMarkFile(
            FileInfo file,
            ClusterComponentType type,
            int errorBufferLength,
            IEpochClock epochClock,
            long timeoutMs)
        {
            var markFileExists = file.Exists;

            markFile = new MarkFile(
                file,
                markFileExists,
                MarkFileHeaderDecoder.VersionEncodingOffset(),
                MarkFileHeaderDecoder.ActivityTimestampEncodingOffset(),
                HEADER_LENGTH + errorBufferLength,
                timeoutMs,
                epochClock,
                (version) =>
            {
                if (VERSION_FAILED == version && markFileExists)
                {
                    Console.WriteLine("mark file version -1 indicates error on previous startup.");
                }
                else if (SemanticVersion.Major(version) != AeronCluster.Configuration.MAJOR_VERSION)
                {
                    throw new ArgumentException("mark file major version " + SemanticVersion.Major(version) +
                                                " does not match software:" + AeronCluster.Configuration.MAJOR_VERSION);
                }
            },
                null);

            buffer      = markFile.Buffer();
            errorBuffer = new UnsafeBuffer(buffer, HEADER_LENGTH, errorBufferLength);


            headerEncoder.Wrap(buffer, 0);
            headerDecoder.Wrap(buffer, 0, MarkFileHeaderDecoder.BLOCK_LENGTH, MarkFileHeaderDecoder.SCHEMA_VERSION);

            if (markFileExists)
            {
                var existingErrorBuffer = new UnsafeBuffer(
                    buffer, headerDecoder.HeaderLength(), headerDecoder.ErrorBufferLength());

                SaveExistingErrors(file, existingErrorBuffer, Console.Error);

                errorBuffer.SetMemory(0, errorBufferLength, 0);
            }
            else
            {
                headerEncoder.CandidateTermId(Aeron.Aeron.NULL_VALUE);
            }

            var existingType = headerDecoder.ComponentType();

            if (existingType != ClusterComponentType.NULL && existingType != type)
            {
                if (existingType != ClusterComponentType.BACKUP || ClusterComponentType.CONSENSUS_MODULE != type)
                {
                    throw new InvalidOperationException(
                              "existing Mark file type " + existingType + " not same as required type " + type);
                }
            }

            headerEncoder.ComponentType(type);
            headerEncoder.HeaderLength(HEADER_LENGTH);
            headerEncoder.ErrorBufferLength(errorBufferLength);
            headerEncoder.Pid(Process.GetCurrentProcess().Id);
            headerEncoder.StartTimestamp(epochClock.Time());
        }
Example #24
0
 /// <summary>
 /// Create a new error log that will be written to a provided <seealso cref="IAtomicBuffer"/>.
 /// </summary>
 /// <param name="buffer"> into which the observation records are recorded. </param>
 /// <param name="clock">  to be used for time stamping records. </param>
 public DistinctErrorLog(IAtomicBuffer buffer, IEpochClock clock)
 {
     buffer.VerifyAlignment();
     _clock = clock;
     _buffer = buffer;
 }
            public void Conclude()
            {
                if (null == threadFactory)
                {
                    threadFactory = new DefaultThreadFactory();
                }

                if (null == idleStrategySupplier)
                {
                    idleStrategySupplier = Configuration.IdleStrategySupplier(null);
                }

                if (null == epochClock)
                {
                    epochClock = new SystemEpochClock();
                }

                if (null == errorHandler)
                {
                    throw new InvalidOperationException("Error handler must be supplied");
                }


                if (null == aeron)
                {
                    aeron = Adaptive.Aeron.Aeron.Connect(
                        new Aeron.Aeron.Context()
                        .AeronDirectoryName(aeronDirectoryName)
                        .ErrorHandler(countedErrorHandler.OnError)
                        .EpochClock(epochClock));

                    if (null == errorCounter)
                    {
                        errorCounter = aeron.AddCounter(SYSTEM_COUNTER_TYPE_ID,
                                                        "Cluster errors - service " + serviceId);
                    }

                    ownsAeronClient = true;
                }

                if (null == errorCounter)
                {
                    throw new InvalidOperationException("Error counter must be supplied");
                }

                if (null == countedErrorHandler)
                {
                    countedErrorHandler = new CountedErrorHandler(errorHandler, errorCounter);
                    if (ownsAeronClient)
                    {
                        aeron.Ctx().ErrorHandler(countedErrorHandler.OnError);
                    }
                }

                if (null == archiveContext)
                {
                    archiveContext = new AeronArchive.Context()
                                     .ControlRequestChannel(AeronArchive.Configuration.LocalControlChannel())
                                     .ControlResponseChannel(AeronArchive.Configuration.LocalControlChannel())
                                     .ControlRequestStreamId(AeronArchive.Configuration.LocalControlStreamId());
                }

                archiveContext
                .AeronClient(aeron)
                .OwnsAeronClient(false)
                .Lock(new NoOpLock());

                if (deleteDirOnStart)
                {
                    if (null != clusteredServiceDir)
                    {
                        IoUtil.Delete(clusteredServiceDir, true);
                    }
                    else
                    {
                        IoUtil.Delete(new DirectoryInfo(Configuration.ClusteredServiceDirName()), true);
                    }
                }

                if (null == clusteredServiceDir)
                {
                    clusteredServiceDir = new DirectoryInfo(clusteredServiceDirectoryName);
                }

                if (!clusteredServiceDir.Exists)
                {
                    Directory.CreateDirectory(clusteredServiceDir.FullName);
                }

                if (null == recordingLog)
                {
                    recordingLog = new RecordingLog(clusteredServiceDir);
                }

                if (null == shutdownSignalBarrier)
                {
                    shutdownSignalBarrier = new ShutdownSignalBarrier();
                }

                if (null == terminationHook)
                {
                    terminationHook = () => shutdownSignalBarrier.Signal();
                }

                if (null == clusteredService)
                {
                    string className = Config.GetProperty(Configuration.SERVICE_CLASS_NAME_PROP_NAME);
                    if (null == className)
                    {
                        throw new InvalidOperationException("Either a ClusteredService instance or class name for the service must be provided");
                    }

                    clusteredService = (IClusteredService)Activator.CreateInstance(Type.GetType(className));
                }

                ConcludeMarkFile();
            }
 /// <summary>
 /// Set the <seealso cref="EpochClock"/> to be used for tracking wall clock time when interacting with the archive.
 /// </summary>
 /// <param name="clock"> <seealso cref="EpochClock"/> to be used for tracking wall clock time when interacting with the archive. </param>
 /// <returns> this for a fluent API. </returns>
 public Context EpochClock(IEpochClock clock)
 {
     this.epochClock = clock;
     return(this);
 }
            public void Conclude()
            {
                if (serviceId < 0)
                {
                    throw new ConfigurationException("service id must be not be negative: " + serviceId);
                }

                if (null == threadFactory)
                {
                    threadFactory = new DefaultThreadFactory();
                }

                if (null == idleStrategySupplier)
                {
                    idleStrategySupplier = Configuration.IdleStrategySupplier(null);
                }

                if (null == epochClock)
                {
                    epochClock = new SystemEpochClock();
                }

                if (null == clusterDir)
                {
                    clusterDir = new DirectoryInfo(clusteredServiceDirectoryName);
                }

                if (!clusterDir.Exists)
                {
                    Directory.CreateDirectory(clusterDir.FullName);
                }

                if (null == markFile)
                {
                    markFile = new ClusterMarkFile(
                        new FileInfo(Path.Combine(clusterDir.FullName, ClusterMarkFile.MarkFilenameForService(serviceId))),
                        ClusterComponentType.CONTAINER,
                        errorBufferLength,
                        epochClock,
                        0);
                }

                if (null == errorLog)
                {
                    errorLog = new DistinctErrorLog(markFile.ErrorBuffer, epochClock);
                }

                if (null == errorHandler)
                {
                    errorHandler = new LoggingErrorHandler(errorLog).OnError; // TODO Use interface
                }

                if (null == aeron)
                {
                    aeron = Adaptive.Aeron.Aeron.Connect(
                        new Aeron.Aeron.Context()
                        .AeronDirectoryName(aeronDirectoryName)
                        .ErrorHandler(errorHandler)
                        .EpochClock(epochClock));

                    ownsAeronClient = true;
                }

                if (null == errorCounter)
                {
                    errorCounter = aeron.AddCounter(SYSTEM_COUNTER_TYPE_ID, "Cluster errors - service " + serviceId);
                }

                if (null == countedErrorHandler)
                {
                    countedErrorHandler = new CountedErrorHandler(errorHandler, errorCounter);
                    if (ownsAeronClient)
                    {
                        aeron.Ctx().ErrorHandler(countedErrorHandler.OnError);
                    }
                }

                if (null == archiveContext)
                {
                    archiveContext = new AeronArchive.Context()
                                     .ControlRequestChannel(AeronArchive.Configuration.LocalControlChannel())
                                     .ControlResponseChannel(AeronArchive.Configuration.LocalControlChannel())
                                     .ControlRequestStreamId(AeronArchive.Configuration.LocalControlStreamId());
                }

                archiveContext
                .AeronClient(aeron)
                .OwnsAeronClient(false)
                .Lock(new NoOpLock());

                if (null == shutdownSignalBarrier)
                {
                    shutdownSignalBarrier = new ShutdownSignalBarrier();
                }

                if (null == terminationHook)
                {
                    terminationHook = () => shutdownSignalBarrier.Signal();
                }

                if (null == clusteredService)
                {
                    string className = Config.GetProperty(Configuration.SERVICE_CLASS_NAME_PROP_NAME);
                    if (null == className)
                    {
                        throw new ClusterException("either a ClusteredService instance or class name for the service must be provided");
                    }

                    clusteredService = (IClusteredService)Activator.CreateInstance(Type.GetType(className));
                }

                ConcludeMarkFile();
            }
Example #28
0
 /// <summary>
 /// Set the <seealso cref="EpochClock"/> to be used for tracking wall clock time when interacting with the driver.
 /// </summary>
 /// <param name="clock"> <seealso cref="EpochClock"/> to be used for tracking wall clock time when interacting with the driver. </param>
 /// <returns> this Aeron.Context for method chaining </returns>
 public Context EpochClock(IEpochClock clock)
 {
     _epochClock = clock;
     return this;
 }
Example #29
0
        public static MappedByteBuffer MapExistingCncFile(FileInfo cncFile, int versionFieldOffset,
                                                          int timestampFieldOffset, long timeoutMs, IEpochClock epochClock, Action <int> versionCheck,
                                                          Action <string> logger)
        {
            long startTimeMs = epochClock.Time();

            while (true)
            {
                while (!cncFile.Exists)
                {
                    if (epochClock.Time() > (startTimeMs + timeoutMs))
                    {
                        throw new InvalidOperationException("CnC file not found: " + cncFile.FullName);
                    }

                    Sleep(16);
                }

                MappedByteBuffer cncByteBuffer = MapExistingFile(cncFile, logger);
                UnsafeBuffer     cncBuffer     = new UnsafeBuffer(cncByteBuffer);

                int cncVersion;
                while (0 == (cncVersion = cncBuffer.GetIntVolatile(versionFieldOffset)))
                {
                    if (epochClock.Time() > (startTimeMs + timeoutMs))
                    {
                        throw new InvalidOperationException("CnC file is created but not initialised.");
                    }

                    Sleep(1);
                }

                versionCheck(cncVersion);

                while (0 == cncBuffer.GetLongVolatile(timestampFieldOffset))
                {
                    if (epochClock.Time() > (startTimeMs + timeoutMs))
                    {
                        throw new InvalidOperationException("No non-0 timestamp detected.");
                    }

                    Sleep(1);
                }

                return(cncByteBuffer);
            }
        }
Example #30
0
        public ClusterMarkFile(FileInfo file, ClusterComponentType type, int totalFileLength, IEpochClock epochClock, long timeoutMs)
        {
            markFile = new MarkFile(file, file.Exists, MarkFileHeaderDecoder.VersionEncodingOffset(), MarkFileHeaderDecoder.ActivityTimestampEncodingOffset(), totalFileLength, timeoutMs, epochClock, (version) =>
            {
                if (version != MarkFileHeaderDecoder.SCHEMA_VERSION)
                {
                    throw new ArgumentException("Mark file version " + version + " does not match software:" + MarkFileHeaderDecoder.SCHEMA_VERSION);
                }
            }, null);

            buffer = markFile.Buffer();

            headerEncoder.Wrap(buffer, 0);
            headerDecoder.Wrap(buffer, 0, MarkFileHeaderDecoder.BLOCK_LENGTH, MarkFileHeaderDecoder.SCHEMA_VERSION);

            var existingType = headerDecoder.ComponentType();

            if (existingType != ClusterComponentType.NULL && existingType != type)
            {
                throw new InvalidOperationException("existing Mark file type " + existingType + " not same as required type " + type);
            }

            headerEncoder.ComponentType(type);
            headerEncoder.Pid(Process.GetCurrentProcess().Id);
        }
Example #31
0
            /// <summary>
            /// This is called automatically by <seealso cref="Connect()"/> and its overloads.
            /// There is no need to call it from a client application. It is responsible for providing default
            /// values for options that are not individually changed through field setters.
            /// </summary>
            /// <returns> this Aeron.Context for method chaining. </returns>
            public Context Conclude()
            {
                try
                {
                    _cncFile = new FileInfo(Path.Combine(_aeronDirectoryName, CncFileDescriptor.CNC_FILE));

                    if (_epochClock == null)
                    {
                        _epochClock = new SystemEpochClock();
                    }

                    if (_nanoClock == null)
                    {
                        _nanoClock = new SystemNanoClock();
                    }

                    if (_idleStrategy == null)
                    {
                        _idleStrategy = new SleepingIdleStrategy(IdleSleepMs);
                    }

                    if (CncFile() != null)
                    {
                        _cncByteBuffer = IoUtil.MapExistingFile(CncFile().FullName);
                        _cncMetaDataBuffer = CncFileDescriptor.CreateMetaDataBuffer(_cncByteBuffer);

                        var cncVersion = _cncMetaDataBuffer.GetInt(CncFileDescriptor.CncVersionOffset(0));

                        if (CncFileDescriptor.CNC_VERSION != cncVersion)
                        {
                            throw new InvalidOperationException(
                                "aeron cnc file version not understood: version=" + cncVersion);
                        }
                    }

                    if (_toClientBuffer == null)
                    {
                        var receiver =
                            new BroadcastReceiver(CncFileDescriptor.CreateToClientsBuffer(_cncByteBuffer,
                                _cncMetaDataBuffer));
                        _toClientBuffer = new CopyBroadcastReceiver(receiver);
                    }

                    if (_toDriverBuffer == null)
                    {
                        _toDriverBuffer =
                            new ManyToOneRingBuffer(CncFileDescriptor.CreateToDriverBuffer(_cncByteBuffer,
                                _cncMetaDataBuffer));
                    }

                    if (CountersMetaDataBuffer() == null)
                    {
                        CountersMetaDataBuffer(CncFileDescriptor.CreateCountersMetaDataBuffer(_cncByteBuffer,
                            _cncMetaDataBuffer));
                    }

                    if (CountersValuesBuffer() == null)
                    {
                        CountersValuesBuffer(CncFileDescriptor.CreateCountersValuesBuffer(_cncByteBuffer,
                            _cncMetaDataBuffer));
                    }

                    _interServiceTimeout = CncFileDescriptor.ClientLivenessTimeout(_cncMetaDataBuffer);

                    if (_logBuffersFactory == null)
                    {
                        _logBuffersFactory = new MappedLogBuffersFactory();
                    }

                    if (_errorHandler == null)
                    {
                        _errorHandler = DEFAULT_ERROR_HANDLER;
                    }

                    if (_availableImageHandler == null)
                    {
                        _availableImageHandler = image => { };
                    }

                    if (_unavailableImageHandler == null)
                    {
                        _unavailableImageHandler = image => { };
                    }
                }
                catch (
                    Exception ex)
                {
                    Console.WriteLine("***");
                    Console.WriteLine("***");
                    Console.WriteLine("Failed to connect to the Media Driver - is it currently running?");
                    Console.WriteLine("***");
                    Console.WriteLine("***");

                    throw new InvalidOperationException("Could not initialise communication buffers", ex);
                }

                return this;
            }
Example #32
0
            /// <summary>
            /// This is called automatically by <seealso cref="Connect()"/> and its overloads.
            /// There is no need to call it from a client application. It is responsible for providing default
            /// values for options that are not individually changed through field setters.
            /// </summary>
            /// <returns> this Aeron.Context for method chaining. </returns>
            public Context Conclude()
            {
                _cncFile = new FileInfo(Path.Combine(_aeronDirectoryName, CncFileDescriptor.CNC_FILE));

                if (_epochClock == null)
                {
                    _epochClock = new SystemEpochClock();
                }

                if (_nanoClock == null)
                {
                    _nanoClock = new SystemNanoClock();
                }

                if (_idleStrategy == null)
                {
                    _idleStrategy = new SleepingIdleStrategy(IdleSleepMs);
                }

                if (CncFile() != null)
                {
                    ConnectToDriver();
                }

                if (_toClientBuffer == null)
                {
                    var receiver =
                        new BroadcastReceiver(CncFileDescriptor.CreateToClientsBuffer(_cncByteBuffer,
                                                                                      _cncMetaDataBuffer));
                    _toClientBuffer = new CopyBroadcastReceiver(receiver);
                }

                if (_toDriverBuffer == null)
                {
                    _toDriverBuffer =
                        new ManyToOneRingBuffer(CncFileDescriptor.CreateToDriverBuffer(_cncByteBuffer,
                                                                                       _cncMetaDataBuffer));
                }

                if (CountersMetaDataBuffer() == null)
                {
                    CountersMetaDataBuffer(CncFileDescriptor.CreateCountersMetaDataBuffer(_cncByteBuffer,
                                                                                          _cncMetaDataBuffer));
                }

                if (CountersValuesBuffer() == null)
                {
                    CountersValuesBuffer(CncFileDescriptor.CreateCountersValuesBuffer(_cncByteBuffer,
                                                                                      _cncMetaDataBuffer));
                }

                _interServiceTimeout = CncFileDescriptor.ClientLivenessTimeout(_cncMetaDataBuffer);

                if (_logBuffersFactory == null)
                {
                    _logBuffersFactory = new MappedLogBuffersFactory();
                }

                if (_errorHandler == null)
                {
                    _errorHandler = DEFAULT_ERROR_HANDLER;
                }

                if (_availableImageHandler == null)
                {
                    _availableImageHandler = image => { };
                }

                if (_unavailableImageHandler == null)
                {
                    _unavailableImageHandler = image => { };
                }

                return(this);
            }
 /// <summary>
 /// Create a new error log that will be written to a provided <seealso cref="IAtomicBuffer"/>.
 /// </summary>
 /// <param name="buffer"> into which the observation records are recorded. </param>
 /// <param name="clock">  to be used for time stamping records. </param>
 public DistinctErrorLog(IAtomicBuffer buffer, IEpochClock clock)
 {
     buffer.VerifyAlignment();
     _clock  = clock;
     _buffer = buffer;
 }