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); }
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); } }
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); }
/// <summary> /// Get the value of the active term count used by the producer of this log. Consumers may have a different /// active term count if they are running behind. The read is done with volatile semantics. /// </summary> /// <param name="metaDataBuffer"> containing the metadata. </param> /// <returns> the value of the active term count used by the producer of this log. </returns> public static int ActiveTermCount(UnsafeBuffer metaDataBuffer) { return(metaDataBuffer.GetIntVolatile(LOG_ACTIVE_TERM_COUNT_OFFSET)); }
/// <summary> /// Get whether the log is considered connected or not by the driver. /// </summary> /// <param name="metaDataBuffer"> containing the metadata. </param> /// <returns> whether the log is considered connected or not by the driver. </returns> public static bool IsConnected(UnsafeBuffer metaDataBuffer) { return(metaDataBuffer.GetIntVolatile(LOG_IS_CONNECTED_OFFSET) == 1); }
/// <summary> /// Get the count of active transports for the Image. /// </summary> /// <param name="metadataBuffer"> containing the meta data. </param> /// <returns> count of active transports. </returns> public static int ActiveTransportCount(UnsafeBuffer metadataBuffer) { return(metadataBuffer.GetIntVolatile(LOG_ACTIVE_TRANSPORT_COUNT)); }
public void ShouldReadFirstMessage() { const int msgLength = 1; int frameLength = HEADER_LENGTH + msgLength; int alignedFrameLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT); const int termOffset = 0; A.CallTo(() => termBuffer.GetIntVolatile(0)) .Returns(frameLength); A.CallTo(() => termBuffer.GetShort(FrameDescriptor.TypeOffset(0))) .Returns((short)HeaderFlyweight.HDR_TYPE_DATA); int readOutcome = TermReader.Read(termBuffer, termOffset, handler, int.MaxValue, header, errorHandler, 0, subscriberPosition); Assert.AreEqual(1, TermReader.FragmentsRead(readOutcome)); A.CallTo(() => termBuffer.GetIntVolatile(0)).MustHaveHappened() .Then(A.CallTo(() => handler.OnFragment(termBuffer, HEADER_LENGTH, msgLength, A <Header> ._)) .MustHaveHappened()) .Then(A.CallTo(() => subscriberPosition.SetOrdered(alignedFrameLength)).MustHaveHappened()); }
public int MemberId() { return(buffer.GetIntVolatile(MarkFileHeaderDecoder.MemberIdEncodingOffset())); }
/// <summary> /// What is the current status of the buffer. /// </summary> /// <returns> the status of buffer as described in <seealso cref="LogBufferDescriptor"/> </returns> public int Status() { return(_metaDataBuffer.GetIntVolatile(LogBufferDescriptor.TERM_STATUS_OFFSET)); }
public virtual int VersionVolatile() { return(buffer.GetIntVolatile(versionFieldOffset)); }
public void ShouldReadFirstMessage() { const int msgLength = 1; int frameLength = HEADER_LENGTH + msgLength; const int termOffset = 0; A.CallTo(() => termBuffer.GetIntVolatile(0)) .Returns(frameLength); A.CallTo(() => termBuffer.GetShort(FrameDescriptor.TypeOffset(0))) .Returns((short)HeaderFlyweight.HDR_TYPE_DATA); long readOutcome = TermReader.Read(termBuffer, termOffset, handler, int.MaxValue, header, errorHandler); Assert.That(TermReader.FragmentsRead(readOutcome), Is.EqualTo(1)); A.CallTo(() => termBuffer.GetIntVolatile(0)).MustHaveHappened(); A.CallTo(() => handler(termBuffer, HEADER_LENGTH, msgLength, A <Header> ._)).MustHaveHappened(); }
/// <summary> /// Get the value of the active partition index used by the producer of this log. Consumers may have a different active /// index if they are running behind. The read is done with volatile semantics. /// </summary> /// <param name="logMetaDataBuffer"> containing the meta data. </param> /// <returns> the value of the active partition index used by the producer of this log. </returns> public static int ActivePartitionIndex(UnsafeBuffer logMetaDataBuffer) { return(logMetaDataBuffer.GetIntVolatile(LOG_ACTIVE_PARTITION_INDEX_OFFSET)); }