public static Counter Allocate(Aeron.Aeron aeron, UnsafeBuffer tempBuffer, long recordingId, int sessionId, int streamId, string strippedChannel, string sourceIdentity) { tempBuffer.PutLong(RECORDING_ID_OFFSET, recordingId); tempBuffer.PutInt(SESSION_ID_OFFSET, sessionId); var sourceIdentityLength = Math.Min(sourceIdentity.Length, CountersReader.MAX_KEY_LENGTH - SOURCE_IDENTITY_OFFSET); tempBuffer.PutStringAscii(SOURCE_IDENTITY_LENGTH_OFFSET, sourceIdentity); var keyLength = SOURCE_IDENTITY_OFFSET + sourceIdentityLength; int labelLength = 0; labelLength += tempBuffer.PutStringWithoutLengthAscii(keyLength, NAME + ": "); labelLength += tempBuffer.PutLongAscii(keyLength + labelLength, recordingId); labelLength += tempBuffer.PutStringWithoutLengthAscii(keyLength + labelLength, " "); labelLength += tempBuffer.PutIntAscii(keyLength + labelLength, sessionId); labelLength += tempBuffer.PutStringWithoutLengthAscii(keyLength + labelLength, " "); labelLength += tempBuffer.PutIntAscii(keyLength + labelLength, streamId); labelLength += tempBuffer.PutStringWithoutLengthAscii(keyLength + labelLength, " "); labelLength += tempBuffer.PutStringWithoutLengthAscii( keyLength + labelLength, strippedChannel, 0, CountersReader.MAX_LABEL_LENGTH - labelLength); return(aeron.AddCounter( RECORDING_POSITION_TYPE_ID, tempBuffer, 0, keyLength, tempBuffer, keyLength, labelLength)); }
public static Counter Allocate(Aeron.Aeron aeron, UnsafeBuffer tempBuffer, long recordingId, long controlSessionId, long correlationId, int sessionId, int streamId, string strippedChannel) { tempBuffer.PutLong(RECORDING_ID_OFFSET, recordingId); tempBuffer.PutLong(CONTROL_SESSION_ID_OFFSET, controlSessionId); tempBuffer.PutLong(CORRELATION_ID_OFFSET, correlationId); tempBuffer.PutInt(SESSION_ID_OFFSET, sessionId); tempBuffer.PutInt(STREAM_ID_OFFSET, streamId); int labelLength = 0; labelLength += tempBuffer.PutStringWithoutLengthAscii(KEY_LENGTH, NAME + ": "); labelLength += tempBuffer.PutLongAscii(KEY_LENGTH + labelLength, recordingId); labelLength += tempBuffer.PutStringWithoutLengthAscii(KEY_LENGTH + labelLength, " "); labelLength += tempBuffer.PutIntAscii(KEY_LENGTH + labelLength, sessionId); labelLength += tempBuffer.PutStringWithoutLengthAscii(KEY_LENGTH + labelLength, " "); labelLength += tempBuffer.PutIntAscii(KEY_LENGTH + labelLength, streamId); labelLength += tempBuffer.PutStringWithoutLengthAscii(KEY_LENGTH + labelLength, " "); labelLength += tempBuffer.PutStringWithoutLengthAscii(KEY_LENGTH + labelLength, strippedChannel, 0, CountersReader.MAX_LABEL_LENGTH - labelLength); return(aeron.AddCounter(RECORDING_POSITION_TYPE_ID, tempBuffer, 0, KEY_LENGTH, tempBuffer, KEY_LENGTH, labelLength)); }
/// <summary> /// Allocate a counter to represent the heartbeat of a clustered service. /// </summary> /// <param name="aeron"> to allocate the counter. </param> /// <param name="tempBuffer"> to use for building the key and label without allocation. </param> /// <param name="serviceId"> of the service heartbeat. </param> /// <returns> the <seealso cref="Counter"/> for the commit position. </returns> public static Counter Allocate(Aeron.Aeron aeron, IMutableDirectBuffer tempBuffer, int serviceId) { int labelOffset = 0; labelOffset += tempBuffer.PutStringWithoutLengthAscii(KEY_LENGTH + labelOffset, NAME); labelOffset += tempBuffer.PutIntAscii(KEY_LENGTH + labelOffset, serviceId); return(aeron.AddCounter(SERVICE_HEARTBEAT_TYPE_ID, tempBuffer, 0, KEY_LENGTH, tempBuffer, KEY_LENGTH, labelOffset)); }
/// <summary> /// Allocate a counter to represent the heartbeat of a clustered service. /// </summary> /// <param name="aeron"> to allocate the counter. </param> /// <param name="tempBuffer"> to use for building the key and label without allocation. </param> /// <param name="serviceId"> of the service heartbeat. </param> /// <returns> the <seealso cref="Counter"/> for the commit position. </returns> public static Counter Allocate(Aeron.Aeron aeron, IMutableDirectBuffer tempBuffer, int serviceId) { tempBuffer.PutInt(SERVICE_ID_OFFSET, serviceId); int labelOffset = BitUtil.Align(KEY_LENGTH, BitUtil.SIZE_OF_INT); int labelLength = 0; labelLength += tempBuffer.PutStringWithoutLengthAscii(labelOffset + labelLength, NAME); labelLength += tempBuffer.PutIntAscii(labelOffset + labelLength, serviceId); return(aeron.AddCounter(SERVICE_HEARTBEAT_TYPE_ID, tempBuffer, 0, KEY_LENGTH, tempBuffer, labelOffset, labelLength)); }
/// <summary> /// Allocate a counter to represent the commit position on stream for the current leadership term. /// </summary> /// <param name="aeron"> to allocate the counter. </param> /// <param name="tempBuffer"> to use for building the key and label without allocation. </param> /// <param name="recordingId"> for the current term. </param> /// <param name="logPosition"> of the log at the beginning of the leadership term. </param> /// <param name="leadershipTermId"> of the log at the beginning of the leadership term. </param> /// <param name="sessionId"> of the active log for the current leadership term. </param> /// <returns> the <seealso cref="Counter"/> for the consensus position. </returns> public static Counter Allocate(Aeron.Aeron aeron, IMutableDirectBuffer tempBuffer, long recordingId, long logPosition, long leadershipTermId, int sessionId) { tempBuffer.PutLong(RECORDING_ID_OFFSET, recordingId); tempBuffer.PutLong(LOG_POSITION_OFFSET, logPosition); tempBuffer.PutLong(LEADERSHIP_TERM_ID_OFFSET, leadershipTermId); tempBuffer.PutInt(SESSION_ID_OFFSET, sessionId); int labelOffset = 0; labelOffset += tempBuffer.PutStringWithoutLengthAscii(KEY_LENGTH + labelOffset, NAME); labelOffset += tempBuffer.PutLongAscii(KEY_LENGTH + labelOffset, leadershipTermId); labelOffset += tempBuffer.PutStringWithoutLengthAscii(KEY_LENGTH + labelOffset, " logSessionId="); labelOffset += tempBuffer.PutIntAscii(KEY_LENGTH + labelOffset, sessionId); return(aeron.AddCounter(COMMIT_POSITION_TYPE_ID, tempBuffer, 0, KEY_LENGTH, tempBuffer, KEY_LENGTH, labelOffset)); }
/// <summary> /// Allocate a counter to represent the snapshot services should load on start. /// </summary> /// <param name="aeron"> to allocate the counter. </param> /// <param name="tempBuffer"> to use for building the key and label without allocation. </param> /// <param name="leadershipTermId"> at which the snapshot was taken. </param> /// <param name="termPosition"> at which the snapshot was taken. </param> /// <param name="timestamp"> the snapshot was taken. </param> /// <param name="replayTermCount"> for the count of terms to be replayed during recovery after snapshot. </param> /// <returns> the <seealso cref="Counter"/> for the consensus position. </returns> public static Counter Allocate(Aeron.Aeron aeron, IMutableDirectBuffer tempBuffer, long termPosition, long leadershipTermId, long timestamp, int replayTermCount) { tempBuffer.PutLong(LEADERSHIP_TERM_ID_OFFSET, leadershipTermId); tempBuffer.PutLong(TERM_POSITION_OFFSET, termPosition); tempBuffer.PutLong(TIMESTAMP_OFFSET, timestamp); tempBuffer.PutInt(REPLAY_TERM_COUNT_OFFSET, replayTermCount); int labelOffset = 0; labelOffset += tempBuffer.PutStringWithoutLengthAscii(KEY_LENGTH + labelOffset, NAME); labelOffset += tempBuffer.PutLongAscii(KEY_LENGTH + labelOffset, leadershipTermId); labelOffset += tempBuffer.PutStringWithoutLengthAscii(KEY_LENGTH + labelOffset, " termPosition="); labelOffset += tempBuffer.PutLongAscii(KEY_LENGTH + labelOffset, termPosition); labelOffset += tempBuffer.PutStringWithoutLengthAscii(KEY_LENGTH + labelOffset, " replayTermCount="); labelOffset += tempBuffer.PutIntAscii(KEY_LENGTH + labelOffset, replayTermCount); return(aeron.AddCounter(RECOVERY_STATE_TYPE_ID, tempBuffer, 0, KEY_LENGTH, tempBuffer, KEY_LENGTH, labelOffset)); }
/// <summary> /// Allocate a counter to represent the commit position on stream for the current leadership term. /// </summary> /// <param name="aeron"> to allocate the counter. </param> /// <param name="tempBuffer"> to use for building the key and label without allocation. </param> /// <param name="leadershipTermId"> of the log at the beginning of the leadership term. </param> /// <param name="termBaseLogPosition"> of the log at the beginning of the leadership term. </param> /// <param name="leadershipTermLength"> length in bytes of the leadership term for the log. </param> /// <returns> the <seealso cref="Counter"/> for the commit position. </returns> public static Counter Allocate( Aeron.Aeron aeron, IMutableDirectBuffer tempBuffer, long leadershipTermId, long termBaseLogPosition, long leadershipTermLength) { tempBuffer.PutLong(LEADERSHIP_TERM_ID_OFFSET, leadershipTermId); tempBuffer.PutLong(TERM_BASE_LOG_POSITION_OFFSET, termBaseLogPosition); tempBuffer.PutLong(LEADERSHIP_TERM_LENGTH_OFFSET, leadershipTermLength); int labelOffset = 0; labelOffset += tempBuffer.PutStringWithoutLengthAscii(KEY_LENGTH + labelOffset, NAME); labelOffset += tempBuffer.PutLongAscii(KEY_LENGTH + labelOffset, leadershipTermId); return(aeron.AddCounter(COMMIT_POSITION_TYPE_ID, tempBuffer, 0, KEY_LENGTH, tempBuffer, KEY_LENGTH, labelOffset)); }
/// <summary> /// Allocate a counter to represent the commit position on stream for the current leadership term. /// </summary> /// <param name="aeron"> to allocate the counter. </param> /// <param name="tempBuffer"> to use for building the key and label without allocation. </param> /// <param name="leadershipTermId"> of the log at the beginning of the leadership term. </param> /// <param name="logPosition"> of the log at the beginning of the leadership term. </param> /// <param name="maxLogPosition"> length in bytes of the leadership term for the log. </param> /// <returns> the <seealso cref="Counter"/> for the commit position. </returns> public static Counter Allocate( Aeron.Aeron aeron, IMutableDirectBuffer tempBuffer, long leadershipTermId, long logPosition, long maxLogPosition) { tempBuffer.PutLong(LEADERSHIP_TERM_ID_OFFSET, leadershipTermId); tempBuffer.PutLong(LOG_POSITION_OFFSET, logPosition); tempBuffer.PutLong(MAX_LOG_POSITION_OFFSET, maxLogPosition); int labelOffset = BitUtil.Align(KEY_LENGTH, BitUtil.SIZE_OF_INT); int labelLength = 0; labelLength += tempBuffer.PutStringWithoutLengthAscii(labelOffset + labelLength, NAME); labelLength += tempBuffer.PutLongAscii(labelOffset + labelLength, leadershipTermId); return(aeron.AddCounter(COMMIT_POSITION_TYPE_ID, tempBuffer, 0, KEY_LENGTH, tempBuffer, labelOffset, labelLength)); }
/// <summary> /// Allocate a counter to represent the snapshot services should load on start. /// </summary> /// <param name="aeron"> to allocate the counter. </param> /// <param name="tempBuffer"> to use for building the key and label without allocation. </param> /// <param name="leadershipTermId"> at which the snapshot was taken. </param> /// <param name="logPosition"> at which the snapshot was taken. </param> /// <param name="timestamp"> the snapshot was taken. </param> /// <param name="hasReplay"> flag is true if all or part of the log must be replayed. </param> /// <param name="snapshotRecordingIds"> for the services to use during recovery indexed by service id. </param> /// <returns> the <seealso cref="Counter"/> for the recovery state. </returns> public static Counter Allocate( Aeron.Aeron aeron, IMutableDirectBuffer tempBuffer, long leadershipTermId, long logPosition, long timestamp, bool hasReplay, params long[] snapshotRecordingIds) { tempBuffer.PutLong(LEADERSHIP_TERM_ID_OFFSET, leadershipTermId); tempBuffer.PutLong(LOG_POSITION_OFFSET, logPosition); tempBuffer.PutLong(TIMESTAMP_OFFSET, timestamp); tempBuffer.PutInt(REPLAY_FLAG_OFFSET, hasReplay ? 1 : 0); int serviceCount = snapshotRecordingIds.Length; tempBuffer.PutInt(SERVICE_COUNT_OFFSET, serviceCount); int keyLength = SNAPSHOT_RECORDING_IDS_OFFSET + (serviceCount * BitUtil.SIZE_OF_LONG); int maxRecordingIdsLength = SNAPSHOT_RECORDING_IDS_OFFSET + (serviceCount * BitUtil.SIZE_OF_LONG); if (maxRecordingIdsLength > CountersReader.MAX_KEY_LENGTH) { throw new ClusterException(maxRecordingIdsLength + " execeeds max key length " + CountersReader.MAX_KEY_LENGTH); } for (int i = 0; i < serviceCount; i++) { tempBuffer.PutLong(SNAPSHOT_RECORDING_IDS_OFFSET + (i * BitUtil.SIZE_OF_LONG), snapshotRecordingIds[i]); } int labelOffset = 0; labelOffset += tempBuffer.PutStringWithoutLengthAscii(keyLength + labelOffset, NAME); labelOffset += tempBuffer.PutLongAscii(keyLength + labelOffset, leadershipTermId); labelOffset += tempBuffer.PutStringWithoutLengthAscii(keyLength + labelOffset, " logPosition="); labelOffset += tempBuffer.PutLongAscii(keyLength + labelOffset, logPosition); labelOffset += tempBuffer.PutStringWithoutLengthAscii(keyLength + labelOffset, " hasReplay=" + hasReplay); return(aeron.AddCounter(RECOVERY_STATE_TYPE_ID, tempBuffer, 0, keyLength, tempBuffer, keyLength, labelOffset)); }
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> /// Allocate a counter to represent the commit position on stream for the current leadership term. /// </summary> /// <param name="aeron"> to allocate the counter. </param> /// <returns> the <seealso cref="Counter"/> for the commit position. </returns> public static Counter Allocate(Aeron.Aeron aeron) { return(aeron.AddCounter(COMMIT_POSITION_TYPE_ID, NAME)); }
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(); }