diff --git a/driver/Aeron.Driver.nuspec b/driver/Aeron.Driver.nuspec index fdef46d1..43fa6e86 100644 --- a/driver/Aeron.Driver.nuspec +++ b/driver/Aeron.Driver.nuspec @@ -2,7 +2,7 @@ Aeron.Driver - 1.9.4 + 1.10.0 Aeron Driver Adaptive Financial Consulting Ltd. Adaptive Financial Consulting Ltd. diff --git a/driver/media-driver.jar b/driver/media-driver.jar index fb89d8fd..82b1502d 100644 Binary files a/driver/media-driver.jar and b/driver/media-driver.jar differ diff --git a/driver/version.txt b/driver/version.txt index 2a38b2a3..19f24320 100644 --- a/driver/version.txt +++ b/driver/version.txt @@ -1,2 +1,4 @@ -Driver source: -http://repo1.maven.org/maven2/io/aeron/aeron-all/1.9.3/aeron-all-1.9.3.jar +Driver built from source +Agrona: 0.9.18-11-gcbee425 +SBE: 1.8.1-31-g337ef8bb +Aeron: 1.9.2-308-gb795fd261 diff --git a/scripts/build-release-nuget-packages - Copy.bat b/scripts/build-release-nuget-packages - Copy.bat new file mode 100644 index 00000000..b62f922d --- /dev/null +++ b/scripts/build-release-nuget-packages - Copy.bat @@ -0,0 +1,12 @@ +@echo off +pushd %~dp0.. + +del nupkgs\*.nupkg + +call dotnet pack src\Adaptive.Aeron\Adaptive.Aeron.csproj -c Release --output ..\..\nupkgs +call dotnet pack src\Adaptive.Agrona\Adaptive.Agrona.csproj -c Release --output ..\..\nupkgs +call dotnet pack src\Adaptive.Cluster\Adaptive.Cluster.csproj -c Release --output ..\..\nupkgs +call dotnet pack src\Adaptive.Archiver\Adaptive.Archiver.csproj -c Release --output ..\..\nupkgs +call .\scripts\nuget pack .\driver\Aeron.Driver.nuspec -OutputDirectory nupkgs + +popd \ No newline at end of file diff --git a/src/Adaptive.Aeron/Adaptive.Aeron.csproj b/src/Adaptive.Aeron/Adaptive.Aeron.csproj index 2d6b8ad3..503ca23e 100644 --- a/src/Adaptive.Aeron/Adaptive.Aeron.csproj +++ b/src/Adaptive.Aeron/Adaptive.Aeron.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 Aeron.Client - 1.9.4 + 1.10.0 Adaptive Financial Consulting Ltd. Adaptive Financial Consulting Ltd. Aeron Client diff --git a/src/Adaptive.Aeron/Aeron.cs b/src/Adaptive.Aeron/Aeron.cs index 1cdf4023..409f1b6c 100644 --- a/src/Adaptive.Aeron/Aeron.cs +++ b/src/Adaptive.Aeron/Aeron.cs @@ -41,6 +41,11 @@ namespace Adaptive.Aeron /// public sealed class Aeron : IDisposable { + /// + /// Used to represent a null value for when some value is not yet set. + /// + public const int NULL_VALUE = -1; + /// /// The Default handler for Aeron runtime exceptions. /// When a is encountered, this handler will @@ -440,7 +445,7 @@ public class Context : IDisposable /// /// Value to represent a sessionId that is not to be used. /// - public const int NULL_SESSION_ID = -1; + public const int NULL_SESSION_ID = Aeron.NULL_VALUE; /// /// Initial term id to be used when creating an . @@ -518,6 +523,11 @@ public class Context : IDisposable /// public const string RELIABLE_STREAM_PARAM_NAME = "reliable"; + /// + /// Key for the tags for a channel + /// + public const string TAGS_PARAM_NAME = "tags"; + /// /// Get the default directory name to be used if is not set. This will take /// the if set and if not then . diff --git a/src/Adaptive.Aeron/ChannelUri.cs b/src/Adaptive.Aeron/ChannelUri.cs index a51b0036..99b58a7b 100644 --- a/src/Adaptive.Aeron/ChannelUri.cs +++ b/src/Adaptive.Aeron/ChannelUri.cs @@ -1,6 +1,9 @@ using System; using System.Collections.Generic; using System.Text; +using Adaptive.Aeron.LogBuffer; +using Adaptive.Agrona.Collections; +using Adaptive.Agrona.Concurrent; namespace Adaptive.Aeron { @@ -37,11 +40,17 @@ private enum State /// public const string SPY_QUALIFIER = "aeron-spy"; + public const long INVALID_TAG = Aeron.NULL_VALUE; + + private const int CHANNEL_TAG_INDEX = 0; + private const int ENTITY_TAG_INDEX = 1; + private static readonly string AERON_PREFIX = AERON_SCHEME + ":"; private string _prefix; private string _media; private readonly IDictionary _params; + private string[] _tags; /// /// Construct with the components provided to avoid parsing. @@ -54,6 +63,8 @@ public ChannelUri(string prefix, string media, IDictionary @para _prefix = prefix; _media = media; _params = @params; + + _tags = SplitTags(_params[Aeron.Context.TAGS_PARAM_NAME]); } /// @@ -151,6 +162,24 @@ public string Put(string key, string value) { return _params[key] = value; } + + /// + /// Remove a key pair in the map of params. + /// + /// of the param to be removed. + /// the previous value of the param or null. + public string Remove(string key) + { + String ret = null; + + if (_params.ContainsKey(key)) + { + ret = _params[key]; + } + + _params.Remove(key); + return ret; + } /// /// Does the URI contain a value for the given key. @@ -162,6 +191,24 @@ public bool ContainsKey(string key) return _params.ContainsKey(key); } + /// + /// Get the channel tag. + /// + /// channel tag. + public string ChannelTag() + { + return (_tags.Length > CHANNEL_TAG_INDEX) ? _tags[CHANNEL_TAG_INDEX] : null; + } + + /// + /// Get the entity tag. + /// + /// entity tag. + public string EntityTag() + { + return (_tags.Length > ENTITY_TAG_INDEX) ? _tags[ENTITY_TAG_INDEX] : null; + } + /// /// Generate a String representation of the URI that is valid for an Aeron channel. /// @@ -201,6 +248,25 @@ public override string ToString() return sb.ToString(); } + /// + /// Initialise a channel for restarting a publication at a given position. + /// + /// at which the publication should be started. + /// what which the stream would start. + /// for the stream. + public void InitialPosition(long position, int initialTermId, int termLength) + { + int bitsToShift = LogBufferDescriptor.PositionBitsToShift(termLength); + int termId = LogBufferDescriptor.ComputeTermIdFromPosition(position, bitsToShift, initialTermId); + int termOffset = (int)(position & (termLength - 1)); + + Put(Aeron.Context.INITIAL_TERM_ID_PARAM_NAME, Convert.ToString(initialTermId)); + Put(Aeron.Context.TERM_ID_PARAM_NAME, Convert.ToString(termId)); + Put(Aeron.Context.TERM_OFFSET_PARAM_NAME, Convert.ToString(termOffset)); + Put(Aeron.Context.TERM_LENGTH_PARAM_NAME, Convert.ToString(termLength)); + } + + /// /// Parse a which contains an Aeron URI. /// @@ -322,12 +388,31 @@ public static ChannelUri Parse(string cs) /// new string that represents channel with sessionId added. public static string AddSessionId(string channel, int sessionId) { - ChannelUri channelUri = ChannelUri.Parse(channel); - + ChannelUri channelUri = Parse(channel); channelUri.Put(Aeron.Context.SESSION_ID_PARAM_NAME, Convert.ToString(sessionId)); return channelUri.ToString(); } + + /// + /// Is the param tagged? That is does it start with the "tag:" prefix. + /// + /// to check if tagged. + /// true if tagged or false if not. + public static bool IsTagged(string paramValue) + { + return StartsWith(paramValue, "tag:"); + } + + /// + /// Get the value of the tag from a given parameter. + /// + /// to extra the tag value from. + /// the value of the tag or if not tagged. + public static long GetTag(string paramValue) + { + return IsTagged(paramValue) ? long.Parse(paramValue.Substring(4, paramValue.Length - 4)) : INVALID_TAG; + } private static bool StartsWith(string input, int position, string prefix) { @@ -351,5 +436,44 @@ private static bool StartsWith(string input, string prefix) { return StartsWith(input, 0, prefix); } + + private static string[] SplitTags(string tags) + { + string[] stringArray = new string[0]; + + if (null != tags) + { + int currentStartIndex = 0; + int tagIndex = 0; + stringArray = new string[2]; + int length = tags.Length; + + for (int i = 0; i < length; i++) + { + if (tags[i] == ',') + { + string tag = null; + + if (i - currentStartIndex > 0) + { + tag = tags.Substring(currentStartIndex, i - currentStartIndex); + currentStartIndex = i + 1; + } + + stringArray = ArrayUtil.EnsureCapacity(stringArray, tagIndex + 1); + stringArray[tagIndex] = tag; + tagIndex++; + } + } + + if ((length - currentStartIndex) > 0) + { + stringArray = ArrayUtil.EnsureCapacity(stringArray, tagIndex + 1); + stringArray[tagIndex] = tags.Substring(currentStartIndex, length - currentStartIndex); + } + } + + return stringArray; + } } } \ No newline at end of file diff --git a/src/Adaptive.Aeron/ChannelUriStringBuilder.cs b/src/Adaptive.Aeron/ChannelUriStringBuilder.cs index a90600e6..bda05484 100644 --- a/src/Adaptive.Aeron/ChannelUriStringBuilder.cs +++ b/src/Adaptive.Aeron/ChannelUriStringBuilder.cs @@ -12,6 +12,8 @@ namespace Adaptive.Aeron /// public class ChannelUriStringBuilder { + public const string TAG_PREFIX = "tag:"; + private readonly StringBuilder _sb = new StringBuilder(64); private string _prefix; @@ -20,6 +22,7 @@ public class ChannelUriStringBuilder private string _networkInterface; private string _controlEndpoint; private string _controlMode; + private string _tags; private bool? _reliable; private int? _ttl; private int? _mtu; @@ -29,6 +32,7 @@ public class ChannelUriStringBuilder private int? _termOffset; private int? _sessionId; private int? _linger; + private bool _isSessionIdTagged; /// /// Clear out all the values thus setting back to the initial state. @@ -42,6 +46,7 @@ public ChannelUriStringBuilder Clear() _networkInterface = null; _controlEndpoint = null; _controlMode = null; + _tags = null; _reliable = null; _ttl = null; _mtu = null; @@ -50,6 +55,7 @@ public ChannelUriStringBuilder Clear() _termId = null; _termOffset = null; _sessionId = null; + _isSessionIdTagged = false; return this; } @@ -460,7 +466,7 @@ public ChannelUriStringBuilder SessionId(int? sessionId) { return _sessionId; } - + /// /// Set the time a publication will linger in nanoseconds after being drained. This time is so that tail loss /// can be recovered. @@ -490,6 +496,66 @@ public ChannelUriStringBuilder Linger(int? lingerNs) return _linger; } + /// + /// Set the tags for a channel, and/or publication or subscription. + /// + /// for the channel, publication or subscription. + /// this for a fluent API. + /// + public ChannelUriStringBuilder Tags(string tags) + { + _tags = tags; + return this; + } + + /// + /// Get the tags for a channel, and/or publication or subscription. + /// + /// the tags for a channel, publication or subscription. + /// + public string Tags() + { + return _tags; + } + + /// + /// Toggle the value for being tagged or not. + /// + /// for session id + /// this for a fluent API. + public ChannelUriStringBuilder IsSessionIdTagged(bool isSessionIdTagged) + { + _isSessionIdTagged = isSessionIdTagged; + return this; + } + + /// + /// Is the value for a tagged. + /// + /// whether the value for a tag reference or not. + public bool IsSessionIdTagged() + { + return _isSessionIdTagged; + } + + /// + /// Initialise a channel for restarting a publication at a given position. + /// + /// at which the publication should be started. + /// what which the stream would start. + /// for the stream. + /// this for a fluent API. + public ChannelUriStringBuilder InitialPosition(long position, int initialTermId, int termLength) + { + int bitsToShift = LogBufferDescriptor.PositionBitsToShift(termLength); + + _initialTermId = initialTermId; + _termId = LogBufferDescriptor.ComputeTermIdFromPosition(position, bitsToShift, initialTermId); + _termOffset = (int) (position & (termLength - 1)); + _termLength = termLength; + + return this; + } /// /// Build a channel URI String for the given parameters. @@ -506,6 +572,11 @@ public string Build() _sb.Append(ChannelUri.AERON_SCHEME).Append(':').Append(_media).Append('?'); + if (null != _tags) + { + _sb.Append(Aeron.Context.TAGS_PARAM_NAME).Append('=').Append(_tags).Append('|'); + } + if (null != _endpoint) { _sb.Append(Aeron.Context.ENDPOINT_PARAM_NAME).Append('=').Append(_endpoint).Append('|'); @@ -565,14 +636,14 @@ public string Build() if (null != _sessionId) { - _sb.Append(Aeron.Context.SESSION_ID_PARAM_NAME).Append('=').Append(_sessionId.Value).Append('|'); + _sb.Append(Aeron.Context.SESSION_ID_PARAM_NAME).Append('=').Append(PrefixTag(_isSessionIdTagged, _sessionId.Value)).Append('|'); } - + if (null != _linger) { _sb.Append(Aeron.Context.LINGER_PARAM_NAME).Append('=').Append(_linger.Value).Append('|'); } - + char lastChar = _sb[_sb.Length - 1]; if (lastChar == '|' || lastChar == '?') { @@ -591,5 +662,10 @@ public string Build() { return null == value ? (int?) null : Convert.ToInt32(value); } + + private static string PrefixTag(bool isTagged, int value) + { + return isTagged ? TAG_PREFIX + value : value.ToString(); + } } } \ No newline at end of file diff --git a/src/Adaptive.Aeron/ClientConductor.cs b/src/Adaptive.Aeron/ClientConductor.cs index b54fdf04..9fa75ec0 100644 --- a/src/Adaptive.Aeron/ClientConductor.cs +++ b/src/Adaptive.Aeron/ClientConductor.cs @@ -35,7 +35,7 @@ namespace Adaptive.Aeron /// internal class ClientConductor : IAgent, IDriverEventsListener { - private const long NO_CORRELATION_ID = -1; + private const long NO_CORRELATION_ID = Aeron.NULL_VALUE; private static readonly long RESOURCE_CHECK_INTERVAL_NS = 1; private static readonly long RESOURCE_LINGER_NS = 3; @@ -496,6 +496,37 @@ internal virtual void RemoveDestination(long registrationId, string endpointChan _clientLock.Unlock(); } } + + internal void AddRcvDestination(long registrationId, string endpointChannel) + { + _clientLock.Lock(); + try + { + EnsureOpen(); + + AwaitResponse(_driverProxy.AddRcvDestination(registrationId, endpointChannel)); + } + finally + { + _clientLock.Unlock(); + } + } + + internal void RemoveRcvDestination(long registrationId, string endpointChannel) + { + _clientLock.Lock(); + try + { + EnsureOpen(); + + AwaitResponse(_driverProxy.RemoveRcvDestination(registrationId, endpointChannel)); + } + finally + { + _clientLock.Unlock(); + } + } + internal virtual Counter AddCounter(int typeId, IDirectBuffer keyBuffer, int keyOffset, int keyLength, IDirectBuffer labelBuffer, int labelOffset, int labelLength) { diff --git a/src/Adaptive.Aeron/Counter.cs b/src/Adaptive.Aeron/Counter.cs index 31409efd..052c51c2 100644 --- a/src/Adaptive.Aeron/Counter.cs +++ b/src/Adaptive.Aeron/Counter.cs @@ -1,4 +1,5 @@ -using Adaptive.Agrona.Concurrent; +using System; +using Adaptive.Agrona.Concurrent; using Adaptive.Agrona.Concurrent.Status; namespace Adaptive.Aeron @@ -23,15 +24,15 @@ internal Counter(long registrationId, ClientConductor clientConductor, IAtomicBu /// Construct a read-write view of an existing counter. /// /// for getting access to the buffers. - /// assigned by the driver for the counter or -1 if not known. + /// assigned by the driver for the counter or if not known. /// for the counter to be viewed. - /// if the id has for the counter has not been allocated. + /// if the id has for the counter has not been allocated. internal Counter(CountersReader countersReader, long registrationId, int counterId) : base( countersReader.ValuesBuffer, counterId) { if (countersReader.GetCounterState(counterId) != CountersReader.RECORD_ALLOCATED) { - throw new System.InvalidOperationException("Counter id has not been allocated: " + counterId); + throw new InvalidOperationException("Counter id has not been allocated: " + counterId); } this.registrationId = registrationId; diff --git a/src/Adaptive.Aeron/DriverEventsAdapter.cs b/src/Adaptive.Aeron/DriverEventsAdapter.cs index 5117a327..c99df47b 100644 --- a/src/Adaptive.Aeron/DriverEventsAdapter.cs +++ b/src/Adaptive.Aeron/DriverEventsAdapter.cs @@ -51,7 +51,7 @@ internal DriverEventsAdapter(CopyBroadcastReceiver broadcastReceiver, IDriverEve public int Receive(long activeCorrelationId) { _activeCorrelationId = activeCorrelationId; - _lastReceivedCorrelationId = -1; + _lastReceivedCorrelationId = Aeron.NULL_VALUE; return _broadcastReceiver.Receive(_messageHandler); } diff --git a/src/Adaptive.Aeron/DriverProxy.cs b/src/Adaptive.Aeron/DriverProxy.cs index 02f50d53..0ce4e0b1 100644 --- a/src/Adaptive.Aeron/DriverProxy.cs +++ b/src/Adaptive.Aeron/DriverProxy.cs @@ -136,7 +136,7 @@ public virtual long AddSubscription(string channel, int streamId) public long AddSubscription(string channel, int streamId) #endif { - const long registrationId = -1; + const long registrationId = Aeron.NULL_VALUE; long correlationId = _toDriverCommandBuffer.NextCorrelationId(); _subscriptionMessage.CorrelationId(correlationId); @@ -207,6 +207,35 @@ public long RemoveDestination(long registrationId, string endpointChannel) return correlationId; } + public long AddRcvDestination(long registrationId, string endpointChannel) + { + long correlationId = _toDriverCommandBuffer.NextCorrelationId(); + + _destinationMessage.RegistrationCorrelationId(registrationId).Channel(endpointChannel).CorrelationId(correlationId); + + if (!_toDriverCommandBuffer.Write(ControlProtocolEvents.ADD_RCV_DESTINATION, _buffer, 0, _destinationMessage.Length())) + { + throw new InvalidOperationException("Could not write rcv destination command"); + } + + return correlationId; + } + + public long RemoveRcvDestination(long registrationId, string endpointChannel) + { + long correlationId = _toDriverCommandBuffer.NextCorrelationId(); + + _destinationMessage.RegistrationCorrelationId(registrationId).Channel(endpointChannel).CorrelationId(correlationId); + + if (!_toDriverCommandBuffer.Write(ControlProtocolEvents.REMOVE_RCV_DESTINATION, _buffer, 0, _destinationMessage.Length())) + { + throw new InvalidOperationException("Could not write rcv destination command"); + } + + return correlationId; + } + + public long AddCounter(int typeId, IDirectBuffer keyBuffer, int keyOffset, int keyLength, IDirectBuffer labelBuffer, int labelOffset, int labelLength) { long correlationId = _toDriverCommandBuffer.NextCorrelationId(); diff --git a/src/Adaptive.Aeron/Exceptions/AeronException.cs b/src/Adaptive.Aeron/Exceptions/AeronException.cs new file mode 100644 index 00000000..1a0120c1 --- /dev/null +++ b/src/Adaptive.Aeron/Exceptions/AeronException.cs @@ -0,0 +1,27 @@ +using System; +using System.Runtime.Serialization; + +namespace Adaptive.Aeron.Exceptions +{ + /// + /// Base Aeron exception for catching all Aeron specific errors. + /// + public class AeronException : Exception + { + public AeronException() + { + } + + protected AeronException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + public AeronException(string message) : base(message) + { + } + + public AeronException(string message, Exception innerException) : base(message, innerException) + { + } + } +} \ No newline at end of file diff --git a/src/Adaptive.Aeron/Exceptions/ChannelEndpointException.cs b/src/Adaptive.Aeron/Exceptions/ChannelEndpointException.cs index 65e51551..da30edb6 100644 --- a/src/Adaptive.Aeron/Exceptions/ChannelEndpointException.cs +++ b/src/Adaptive.Aeron/Exceptions/ChannelEndpointException.cs @@ -1,8 +1,6 @@ -using System; - -namespace Adaptive.Aeron.Exceptions +namespace Adaptive.Aeron.Exceptions { - public class ChannelEndpointException : Exception + public class ChannelEndpointException : AeronException { public ChannelEndpointException(int statusIndicatorId, string message) : base(message) { diff --git a/src/Adaptive.Aeron/Exceptions/ConfigurationException.cs b/src/Adaptive.Aeron/Exceptions/ConfigurationException.cs new file mode 100644 index 00000000..340eb3dd --- /dev/null +++ b/src/Adaptive.Aeron/Exceptions/ConfigurationException.cs @@ -0,0 +1,9 @@ +namespace Adaptive.Aeron.Exceptions +{ + public class ConfigurationException : AeronException + { + public ConfigurationException(string message) : base(message) + { + } + } +} \ No newline at end of file diff --git a/src/Adaptive.Aeron/Exceptions/RegistrationException.cs b/src/Adaptive.Aeron/Exceptions/RegistrationException.cs index 8e2263b3..e205dd91 100644 --- a/src/Adaptive.Aeron/Exceptions/RegistrationException.cs +++ b/src/Adaptive.Aeron/Exceptions/RegistrationException.cs @@ -14,21 +14,19 @@ * limitations under the License. */ -using System; - namespace Adaptive.Aeron.Exceptions { /// /// Caused when a error occurs during addition or release of s /// or s /// - public class RegistrationException : Exception + public class RegistrationException : AeronException { private readonly ErrorCode _code; public RegistrationException(ErrorCode code, string msg) : base(msg) { - this._code = code; + _code = code; } /// diff --git a/src/Adaptive.Aeron/Protocol/DataHeaderFlyweight.cs b/src/Adaptive.Aeron/Protocol/DataHeaderFlyweight.cs index 7f4f465f..b6a3e7b2 100644 --- a/src/Adaptive.Aeron/Protocol/DataHeaderFlyweight.cs +++ b/src/Adaptive.Aeron/Protocol/DataHeaderFlyweight.cs @@ -23,9 +23,10 @@ namespace Adaptive.Aeron.Protocol { /// - /// HeaderFlyweight for Data Header + /// HeaderFlyweight for Data Frame header of a message fragment. /// - /// Data Frame + /// Data Frame + /// wiki page. /// public class DataHeaderFlyweight : HeaderFlyweight { diff --git a/src/Adaptive.Aeron/Protocol/HeaderFlyweight.cs b/src/Adaptive.Aeron/Protocol/HeaderFlyweight.cs index 8a8bd058..269e4926 100644 --- a/src/Adaptive.Aeron/Protocol/HeaderFlyweight.cs +++ b/src/Adaptive.Aeron/Protocol/HeaderFlyweight.cs @@ -21,7 +21,7 @@ namespace Adaptive.Aeron.Protocol { /// - /// Flyweight for general Aeron network protocol header + /// Flyweight for general Aeron network protocol header of a message frame. /// /// 0 1 2 3 /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 diff --git a/src/Adaptive.Aeron/Protocol/RttMeasurementFlyweight.cs b/src/Adaptive.Aeron/Protocol/RttMeasurementFlyweight.cs deleted file mode 100644 index ea6888a9..00000000 --- a/src/Adaptive.Aeron/Protocol/RttMeasurementFlyweight.cs +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2014 - 2017 Adaptive Financial Consulting Ltd - * - * 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 - * - * http://www.apache.org/licenses/LICENSE-2.0S - * - * 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. - */ - -using System.Text; -using Adaptive.Agrona.Concurrent; - -namespace Adaptive.Aeron.Protocol -{ - /// - /// Flyweight for an RTT Measurement Packet - /// - /// - /// RTT Measurement Header - /// - public class RttMeasurementFlyweight : HeaderFlyweight - { - public const short REPLY_FLAG = 0x80; - public const int HEADER_LENGTH = 40; - - private const int SESSION_ID_FIELD_OFFSET = 8; - private const int STREAM_ID_FIELD_OFFSET = 12; - private const int ECHO_TIMESTAMP_FIELD_OFFSET = 16; - private const int RECEPTION_DELTA_FIELD_OFFSET = 24; - private const int RECEIVER_ID_FIELD_OFFSET = 32; - - public RttMeasurementFlyweight() - { - } - - public RttMeasurementFlyweight(UnsafeBuffer buffer) : base(buffer) - { - } - - /// - /// return session id field - /// - /// session id field - public virtual int SessionId() - { - return GetInt(SESSION_ID_FIELD_OFFSET); - } - - /// - /// set session id field - /// - /// field value - /// flyweight - public virtual RttMeasurementFlyweight SessionId(int sessionId) - { - PutInt(SESSION_ID_FIELD_OFFSET, sessionId); - - return this; - } - - /// - /// return stream id field - /// - /// stream id field - public virtual int StreamId() - { - return GetInt(STREAM_ID_FIELD_OFFSET); - } - - /// - /// set stream id field - /// - /// field value - /// flyweight - public virtual RttMeasurementFlyweight StreamId(int streamId) - { - PutInt(STREAM_ID_FIELD_OFFSET, streamId); - - return this; - } - - public virtual long EchoTimestampNs() - { - return GetLong(ECHO_TIMESTAMP_FIELD_OFFSET); - } - - public virtual RttMeasurementFlyweight EchoTimestampNs(long timestamp) - { - PutLong(ECHO_TIMESTAMP_FIELD_OFFSET, timestamp); - - return this; - } - - public virtual long ReceptionDelta() - { - return GetLong(RECEPTION_DELTA_FIELD_OFFSET); - } - - public virtual RttMeasurementFlyweight ReceptionDeltaFlyweight(long delta) - { - PutLong(RECEPTION_DELTA_FIELD_OFFSET, delta); - - return this; - } - - public virtual long ReceiverId() - { - return GetLong(RECEIVER_ID_FIELD_OFFSET); - } - - public virtual RttMeasurementFlyweight ReceiverId(long id) - { - PutLong(RECEIVER_ID_FIELD_OFFSET, id); - - return this; - } - - public override string ToString() - { - StringBuilder sb = new StringBuilder(); - // TODO string formattedFlags = string.Format("{0,8}", Integer.toBinaryString(Flags())).Replace(' ', '0'); - string formattedFlags = string.Empty; - - sb.Append("RTT Measure Message{") - .Append("frame_length=").Append(FrameLength()) - .Append(" version=").Append(Version()) - .Append(" flags=").Append(formattedFlags) - .Append(" type=").Append(HeaderType()) - .Append(" session_id=").Append(SessionId()) - .Append(" stream_id=").Append(StreamId()) - .Append(" echo_timestamp=").Append(EchoTimestampNs()) - .Append(" reception_delta=").Append(ReceptionDelta()) - .Append(" receiver_id=").Append(ReceiverId()).Append("}"); - - return sb.ToString(); - } - } -} \ No newline at end of file diff --git a/src/Adaptive.Aeron/Status/ChannelEndpointStatus.cs b/src/Adaptive.Aeron/Status/ChannelEndpointStatus.cs index 0b3794b4..be79fa28 100644 --- a/src/Adaptive.Aeron/Status/ChannelEndpointStatus.cs +++ b/src/Adaptive.Aeron/Status/ChannelEndpointStatus.cs @@ -31,7 +31,7 @@ public class ChannelEndpointStatus /// /// No counter ID is allocated yet. /// - public const int NO_ID_ALLOCATED = -1; + public const int NO_ID_ALLOCATED = Aeron.NULL_VALUE; /// /// Offset in the key meta data for the channel of the counter. diff --git a/src/Adaptive.Aeron/Status/HeartbeatStatus.cs b/src/Adaptive.Aeron/Status/HeartbeatStatus.cs deleted file mode 100644 index 082660da..00000000 --- a/src/Adaptive.Aeron/Status/HeartbeatStatus.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Adaptive.Agrona; -using Adaptive.Agrona.Concurrent.Status; - -namespace Adaptive.Aeron.Status -{ - /// - /// Allocate a counter for tracking the last heartbeat of an entity. - /// - public class HeartbeatStatus - { - /// - /// Offset in the key meta data for the registration id of the counter. - /// - public const int REGISTRATION_ID_OFFSET = 0; - - /// - /// Allocate a counter for tracking the last heartbeat of an entity. - /// - /// to be used for labels and key. - /// of the counter for the label. - /// of the counter for classification. - /// from which to allocated the underlying storage. - /// to be associated with the counter. - /// a new for tracking the last heartbeat. - public static AtomicCounter Allocate( - IMutableDirectBuffer tempBuffer, - string name, - int typeId, - CountersManager countersManager, - long registrationId) - { - return new AtomicCounter(countersManager.ValuesBuffer, - AllocateCounterId(tempBuffer, name, typeId, countersManager, registrationId), countersManager); - } - - public static int AllocateCounterId( - IMutableDirectBuffer tempBuffer, - string name, - int typeId, - CountersManager countersManager, - long registrationId) - { - tempBuffer.PutLong(REGISTRATION_ID_OFFSET, registrationId); - int keyLength = REGISTRATION_ID_OFFSET + BitUtil.SIZE_OF_LONG; - - int labelLength = 0; - labelLength += tempBuffer.PutStringWithoutLengthAscii(keyLength + labelLength, name); - labelLength += tempBuffer.PutStringWithoutLengthAscii(keyLength + labelLength, ": "); - labelLength += tempBuffer.PutLongAscii(keyLength + labelLength, registrationId); - - return countersManager.Allocate(typeId, tempBuffer, 0, keyLength, tempBuffer, keyLength, labelLength); - } - } -} \ No newline at end of file diff --git a/src/Adaptive.Aeron/Status/ReadableCounter.cs b/src/Adaptive.Aeron/Status/ReadableCounter.cs index 472cc7a1..751d160d 100644 --- a/src/Adaptive.Aeron/Status/ReadableCounter.cs +++ b/src/Adaptive.Aeron/Status/ReadableCounter.cs @@ -27,7 +27,7 @@ public class ReadableCounter : IDisposable /// Construct a view of an existing counter. /// /// for getting access to the buffers. - /// assigned by the driver for the counter or -1 if not known. + /// assigned by the driver for the counter or if not known. /// for the counter to be viewed. /// if the id has for the counter has not been allocated. public ReadableCounter(CountersReader countersReader, long registrationId, int counterId) @@ -55,7 +55,7 @@ public ReadableCounter(CountersReader countersReader, long registrationId, int c /// for getting access to the buffers. /// for the counter to be viewed. /// if the id has for the counter has not been allocated. - public ReadableCounter(CountersReader countersReader, int counterId) : this(countersReader, -1, counterId) + public ReadableCounter(CountersReader countersReader, int counterId) : this(countersReader, Aeron.NULL_VALUE, counterId) { } diff --git a/src/Adaptive.Aeron/Subscription.cs b/src/Adaptive.Aeron/Subscription.cs index b2136ffc..2a957285 100644 --- a/src/Adaptive.Aeron/Subscription.cs +++ b/src/Adaptive.Aeron/Subscription.cs @@ -440,7 +440,36 @@ public long ChannelStatus() return _fields.conductor.ChannelStatus(ChannelStatusId); } + + /// + /// Add a destination manually to a multi-destination Subscription. + /// + /// for the destination to add + public void AddDestination(string endpointChannel) + { + if (_fields.isClosed) + { + throw new InvalidOperationException("Subscription is closed"); + } + _fields.conductor.AddRcvDestination(_fields.registrationId, endpointChannel); + } + + /// + /// Remove a previously added destination from a multi-destination Subscription. + /// + /// for the destination to remove + public void RemoveDestination(string endpointChannel) + { + if (_fields.isClosed) + { + throw new InvalidOperationException("Subscription is closed"); + } + + _fields.conductor.RemoveRcvDestination(_fields.registrationId, endpointChannel); + } + + internal int ChannelStatusId { get => _fields.channelStatusId; diff --git a/src/Adaptive.Agrona/Adaptive.Agrona.csproj b/src/Adaptive.Agrona/Adaptive.Agrona.csproj index 6dd660b9..efc032be 100644 --- a/src/Adaptive.Agrona/Adaptive.Agrona.csproj +++ b/src/Adaptive.Agrona/Adaptive.Agrona.csproj @@ -3,7 +3,7 @@ netstandard2.0;net45 true Agrona - 1.9.4 + 1.10.0 Adaptive Financial Consulting Ltd. Adaptive Financial Consulting Ltd. Agrona libraries initially included in Aeron Client diff --git a/src/Adaptive.Archiver/Adaptive.Archiver.csproj b/src/Adaptive.Archiver/Adaptive.Archiver.csproj index e7f2747f..60dadea4 100644 --- a/src/Adaptive.Archiver/Adaptive.Archiver.csproj +++ b/src/Adaptive.Archiver/Adaptive.Archiver.csproj @@ -3,7 +3,7 @@ netstandard2.0;net45 true Aeron.Archiver - 1.9.4 + 1.10.0 Adaptive Financial Consulting Ltd. Adaptive Financial Consulting Ltd. Archiving over the Aeron transport diff --git a/src/Adaptive.Archiver/AeronArchive.cs b/src/Adaptive.Archiver/AeronArchive.cs index 835b7401..544eed31 100644 --- a/src/Adaptive.Archiver/AeronArchive.cs +++ b/src/Adaptive.Archiver/AeronArchive.cs @@ -23,17 +23,17 @@ public class AeronArchive : IDisposable /// /// Represents a timestamp that has not been set. Can be used when the time is not known. /// - public const long NULL_TIMESTAMP = -1L; + public const long NULL_TIMESTAMP = Aeron.Aeron.NULL_VALUE; /// /// Represents a position that has not been set. Can be used when the position is not known. /// - public const long NULL_POSITION = -1L; - + public const long NULL_POSITION = Aeron.Aeron.NULL_VALUE; + /// /// Represents a length that has not been set. If null length is provided then replay the whole recorded stream. /// - public const long NULL_LENGTH = -1L; + public const long NULL_LENGTH = Aeron.Aeron.NULL_VALUE; private const int FRAGMENT_LIMIT = 10; @@ -76,7 +76,7 @@ internal AeronArchive(Context ctx) if (!archiveProxy.Connect(ctx.ControlResponseChannel(), ctx.ControlResponseStreamId(), correlationId, aeronClientInvoker)) { - throw new InvalidOperationException( + throw new ArchiveException( "cannot connect to aeron archive: " + ctx.ControlRequestChannel()); } @@ -293,16 +293,27 @@ public string PollForErrorResponse() /// public virtual void CheckForErrorResponse() { - var errorMessage = PollForErrorResponse(); - if (null != errorMessage) + _lock.Lock(); + try + { + if (controlResponsePoller.Poll() != 0 && controlResponsePoller.IsPollComplete()) + { + if (controlResponsePoller.TemplateId() == ControlResponseDecoder.TEMPLATE_ID && + controlResponsePoller.Code() == ControlResponseCode.ERROR) + { + throw new ArchiveException(controlResponsePoller.ErrorMessage(), (int) controlResponsePoller.RelevantId()); + } + } + } + finally { - throw new ArchiveException(errorMessage); + _lock.Unlock(); } } /// /// Add a and set it up to be recorded. If this is not the first, - /// i.e. is true, then an + /// i.e. is true, then an /// will be thrown and the recording not initiated. /// /// This is a sessionId specific recording. @@ -323,7 +334,7 @@ public Publication AddRecordedPublication(string channel, int streamId) { publication.Dispose(); - throw new InvalidOperationException( + throw new ArchiveException( "publication already added for channel=" + channel + " streamId=" + streamId); } @@ -397,7 +408,7 @@ public long StartRecording(string channel, int streamId, SourceLocation sourceLo if (!archiveProxy.StartRecording(channel, streamId, sourceLocation, correlationId, controlSessionId)) { - throw new InvalidOperationException("failed to send start recording request"); + throw new ArchiveException("failed to send start recording request"); } PollForResponse(correlationId); @@ -433,7 +444,7 @@ public long ExtendRecording(long recordingId, string channel, int streamId, if (!archiveProxy.ExtendRecording(channel, streamId, sourceLocation, recordingId, correlationId, controlSessionId)) { - throw new InvalidOperationException("failed to send extend recording request"); + throw new ArchiveException("failed to send extend recording request"); } PollForResponse(correlationId); @@ -466,7 +477,7 @@ public void StopRecording(string channel, int streamId) if (!archiveProxy.StopRecording(channel, streamId, correlationId, controlSessionId)) { - throw new InvalidOperationException("failed to send stop recording request"); + throw new ArchiveException("failed to send stop recording request"); } PollForResponse(correlationId); @@ -510,7 +521,7 @@ public long StartReplay(long recordingId, long position, long length, string rep if (!archiveProxy.Replay(recordingId, position, length, replayChannel, replayStreamId, correlationId, controlSessionId)) { - throw new InvalidOperationException("failed to send replay request"); + throw new ArchiveException("failed to send replay request"); } return PollForResponse(correlationId); @@ -534,7 +545,7 @@ public void StopReplay(long replaySessionId) if (!archiveProxy.StopReplay(replaySessionId, correlationId, controlSessionId)) { - throw new InvalidOperationException("failed to send stop recording request"); + throw new ArchiveException("failed to send stop recording request"); } PollForResponse(correlationId); @@ -547,11 +558,11 @@ public void StopReplay(long replaySessionId) /// /// Replay a length in bytes of a recording from a position and for convenience create a - /// to receive the replay. If the position is then the stream will be replayed from the start. + /// to receive the replay. If the position is then the stream will be replayed from the start. /// /// to be replayed. - /// from which the replay should begin or if from the start. - /// of the stream to be replayed or to follow a live recording. + /// from which the replay should begin or if from the start. + /// of the stream to be replayed or to follow a live recording. /// to which the replay should be sent. /// to which the replay should be sent. /// the for consuming the replay. @@ -567,7 +578,7 @@ public Subscription Replay(long recordingId, long position, long length, string if (!archiveProxy.Replay(recordingId, position, length, replayChannel, replayStreamId, correlationId, controlSessionId)) { - throw new InvalidOperationException("failed to send replay request"); + throw new ArchiveException("failed to send replay request"); } int replaySessionId = (int) PollForResponse(correlationId); @@ -606,7 +617,7 @@ public Subscription Replay(long recordingId, long position, long length, string if (!archiveProxy.Replay(recordingId, position, length, replayChannel, replayStreamId, correlationId, controlSessionId)) { - throw new InvalidOperationException("failed to send replay request"); + throw new ArchiveException("failed to send replay request"); } int replaySessionId = (int) PollForResponse(correlationId); @@ -641,7 +652,7 @@ public int ListRecordings(long fromRecordingId, int recordCount, IRecordingDescr if (!archiveProxy.ListRecordings(fromRecordingId, recordCount, correlationId, controlSessionId)) { - throw new InvalidOperationException("failed to send list recordings request"); + throw new ArchiveException("failed to send list recordings request"); } return PollForDescriptors(correlationId, recordCount, consumer); @@ -676,7 +687,7 @@ public int ListRecordingsForUri(long fromRecordingId, int recordCount, string ch if (!archiveProxy.ListRecordingsForUri(fromRecordingId, recordCount, channel, streamId, correlationId, controlSessionId)) { - throw new InvalidOperationException("failed to send list recordings request"); + throw new ArchiveException("failed to send list recordings request"); } return PollForDescriptors(correlationId, recordCount, consumer); @@ -706,7 +717,7 @@ public int ListRecording(long recordingId, IRecordingDescriptorConsumer consumer if (!archiveProxy.ListRecording(recordingId, correlationId, controlSessionId)) { - throw new InvalidOperationException("failed to send list recording request"); + throw new ArchiveException("failed to send list recording request"); } return PollForDescriptors(correlationId, 1, consumer); @@ -731,7 +742,7 @@ public long GetRecordingPosition(long recordingId) if (!archiveProxy.GetRecordingPosition(recordingId, correlationId, controlSessionId)) { - throw new InvalidOperationException("failed to send get recording position request"); + throw new ArchiveException("failed to send get recording position request"); } return PollForResponse(correlationId); @@ -757,7 +768,7 @@ public void TruncateRecording(long recordingId, long position) if (!archiveProxy.TruncateRecording(recordingId, position, correlationId, controlSessionId)) { - throw new InvalidOperationException("failed to send truncate recording request"); + throw new ArchiveException("failed to send truncate recording request"); } PollForResponse(correlationId); @@ -791,10 +802,10 @@ private long AwaitSessionOpened(long correlationId) { if (code == ControlResponseCode.ERROR) { - throw new InvalidOperationException("error: " + poller.ErrorMessage()); + throw new ArchiveException("error: " + poller.ErrorMessage(), (int) poller.RelevantId()); } - throw new InvalidOperationException("unexpected response: code=" + code); + throw new ArchiveException("unexpected response: code=" + code); } return poller.ControlSessionId(); @@ -835,14 +846,14 @@ private long PollForResponse(long correlationId) if (poller.Code() == ControlResponseCode.ERROR) { - throw new InvalidOperationException("response for correlationId=" + correlationId + ", error: " + - poller.ErrorMessage()); + throw new ArchiveException("response for correlationId=" + correlationId + ", error: " + + poller.ErrorMessage(), (int) poller.RelevantId()); } ControlResponseCode code = poller.Code(); if (ControlResponseCode.OK != code) { - throw new InvalidOperationException("unexpected response code: " + code); + throw new ArchiveException("unexpected response code: " + code); } if (poller.CorrelationId() == correlationId) @@ -872,7 +883,7 @@ private void PollNextResponse(long correlationId, long deadlineNs, ControlRespon if (!poller.Subscription().IsConnected) { - throw new InvalidOperationException("subscription to archive is not connected"); + throw new ArchiveException("subscription to archive is not connected"); } if (nanoClock.NanoTime() > deadlineNs) @@ -910,7 +921,7 @@ private int PollForDescriptors(long correlationId, int recordCount, IRecordingDe if (!poller.Subscription().IsConnected) { - throw new InvalidOperationException("subscription to archive is not connected"); + throw new ArchiveException("subscription to archive is not connected"); } if (nanoClock.NanoTime() > deadlineNs) @@ -1563,7 +1574,7 @@ public class AsyncConnect : IDisposable private readonly Context ctx; private readonly ControlResponsePoller controlResponsePoller; private readonly ArchiveProxy archiveProxy; - private long connectCorrelationId = -1; + private long connectCorrelationId = Aeron.Aeron.NULL_VALUE; private int step = 0; internal AsyncConnect(Context ctx, ControlResponsePoller controlResponsePoller, ArchiveProxy archiveProxy) @@ -1635,10 +1646,10 @@ public AeronArchive Poll() { if (code == ControlResponseCode.ERROR) { - throw new InvalidOperationException("error: " + controlResponsePoller.ErrorMessage()); + throw new ArchiveException("error: " + controlResponsePoller.ErrorMessage(), (int) controlResponsePoller.RelevantId()); } - throw new InvalidOperationException("unexpected response: code=" + code); + throw new ArchiveException("unexpected response: code=" + code); } long controlSessionId = controlResponsePoller.ControlSessionId(); diff --git a/src/Adaptive.Archiver/ArchiveException.cs b/src/Adaptive.Archiver/ArchiveException.cs index c9d26f1e..111f5fdf 100644 --- a/src/Adaptive.Archiver/ArchiveException.cs +++ b/src/Adaptive.Archiver/ArchiveException.cs @@ -1,19 +1,44 @@ using System; +using Adaptive.Aeron.Exceptions; namespace Adaptive.Archiver { - public class ArchiveException : Exception + public class ArchiveException : AeronException { + public const int GENERIC = 0; + public const int ACTIVE_LISTING = 1; + public const int ACTIVE_RECORDING = 2; + public const int ACTIVE_SUBSCRIPTION = 3; + public const int UNKNOWN_SUBSCRIPTION = 4; + public const int UNKNOWN_RECORDING = 5; + public const int UNKNOWN_REPLAY = 6; + public const int MAX_REPLAYS = 7; + public const int MAX_RECORDINGS = 8; + + /// + /// Error code providing more detail into what went wrong. + /// + /// code providing more detail into what went wrong. + public int ErrorCode { get; } + public ArchiveException() { + ErrorCode = GENERIC; } public ArchiveException(string message) : base(message) { + ErrorCode = GENERIC; } - public ArchiveException(string message, Exception innerException) : base(message, innerException) + public ArchiveException(string message, int errorCode) : base(message) { + ErrorCode = errorCode; + } + + public ArchiveException(string message, Exception innerException, int errorCode) : base(message, innerException) + { + ErrorCode = errorCode; } } } \ No newline at end of file diff --git a/src/Adaptive.Archiver/ArchiveProxy.cs b/src/Adaptive.Archiver/ArchiveProxy.cs index 29182e32..f7c909db 100644 --- a/src/Adaptive.Archiver/ArchiveProxy.cs +++ b/src/Adaptive.Archiver/ArchiveProxy.cs @@ -373,17 +373,17 @@ private bool Offer(int length) if (result == Publication.CLOSED) { - throw new System.InvalidOperationException("connection to the archive has been closed"); + throw new ArchiveException("connection to the archive has been closed"); } if (result == Publication.NOT_CONNECTED) { - throw new System.InvalidOperationException("connection to the archive is no longer available"); + throw new ArchiveException("connection to the archive is no longer available"); } if (result == Publication.MAX_POSITION_EXCEEDED) { - throw new System.InvalidOperationException("publication failed due to max position being reached"); + throw new ArchiveException("offer failed due to max position being reached"); } if (--attempts <= 0) @@ -415,12 +415,12 @@ private bool OfferWithTimeout(int length, AgentInvoker aeronClientInvoker) if (result == Publication.CLOSED) { - throw new System.InvalidOperationException("connection to the archive has been closed"); + throw new ArchiveException("connection to the archive has been closed"); } if (result == Publication.MAX_POSITION_EXCEEDED) { - throw new System.InvalidOperationException("publication failed due to max position being reached"); + throw new ArchiveException("offer failed due to max position being reached"); } if (nanoClock.NanoTime() > deadlineNs) diff --git a/src/Adaptive.Archiver/Codecs/ControlResponseDecoder.cs b/src/Adaptive.Archiver/Codecs/ControlResponseDecoder.cs index ed4b6524..a13ab2c7 100644 --- a/src/Adaptive.Archiver/Codecs/ControlResponseDecoder.cs +++ b/src/Adaptive.Archiver/Codecs/ControlResponseDecoder.cs @@ -403,7 +403,7 @@ public StringBuilder AppendTo(StringBuilder builder) builder.Append("CorrelationId="); builder.Append(CorrelationId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='relevantId', referencedName='null', description='Relevant identity of requested object, e.g. recordingId if RECORDING_UNKNOWN', id=3, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='relevantId', referencedName='null', description='Relevant identity of an object, e.g. recordingId if RECORDING_UNKNOWN, or error code', id=3, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("RelevantId="); builder.Append(RelevantId()); diff --git a/src/Adaptive.Archiver/ControlResponseAdaptor.cs b/src/Adaptive.Archiver/ControlResponseAdaptor.cs index 55c11b93..275625e5 100644 --- a/src/Adaptive.Archiver/ControlResponseAdaptor.cs +++ b/src/Adaptive.Archiver/ControlResponseAdaptor.cs @@ -1,8 +1,6 @@ -using System; -using Adaptive.Aeron; +using Adaptive.Aeron; using Adaptive.Aeron.LogBuffer; using Adaptive.Agrona; -using Adaptive.Agrona.Concurrent; using Adaptive.Archiver.Codecs; namespace Adaptive.Archiver @@ -82,7 +80,7 @@ public virtual void OnFragment(IDirectBuffer buffer, int offset, int length, Hea break; default: - throw new InvalidOperationException("unknown templateId: " + templateId); + throw new ArchiveException("unknown templateId: " + templateId); } } diff --git a/src/Adaptive.Archiver/ControlResponsePoller.cs b/src/Adaptive.Archiver/ControlResponsePoller.cs index 754f4cce..e5a3e174 100644 --- a/src/Adaptive.Archiver/ControlResponsePoller.cs +++ b/src/Adaptive.Archiver/ControlResponsePoller.cs @@ -24,10 +24,10 @@ private void InitializeInstanceFields() private readonly Subscription subscription; private ControlledFragmentAssembler fragmentAssembler; - private long controlSessionId = -1; - private long correlationId = -1; - private long relevantId = -1; - private int templateId = -1; + private long controlSessionId = Aeron.Aeron.NULL_VALUE; + private long correlationId = Aeron.Aeron.NULL_VALUE; + private long relevantId = Aeron.Aeron.NULL_VALUE; + private int templateId = Aeron.Aeron.NULL_VALUE; private ControlResponseCode code; private string errorMessage; private bool pollComplete = false; @@ -72,18 +72,18 @@ public virtual int Poll() } /// - /// Control session id of the last polled message or -1 if poll returned nothing. + /// Control session id of the last polled message or if poll returned nothing. /// - /// control session id of the last polled message or -1 if unrecognised template. + /// control session id of the last polled message or if unrecognised template. public virtual long ControlSessionId() { return controlSessionId; } /// - /// Correlation id of the last polled message or -1 if poll returned nothing. + /// Correlation id of the last polled message or if poll returned nothing. /// - /// correlation id of the last polled message or -1 if unrecognised template. + /// correlation id of the last polled message or if unrecognised template. public virtual long CorrelationId() { return correlationId; @@ -163,7 +163,7 @@ public virtual ControlledFragmentHandlerAction OnFragment(IDirectBuffer buffer, break; default: - throw new System.InvalidOperationException("unknown templateId: " + templateId); + throw new ArchiveException("unknown templateId: " + templateId); } pollComplete = true; diff --git a/src/Adaptive.Archiver/RecordingDescriptorPoller.cs b/src/Adaptive.Archiver/RecordingDescriptorPoller.cs index 63d43db0..10f6bfd9 100644 --- a/src/Adaptive.Archiver/RecordingDescriptorPoller.cs +++ b/src/Adaptive.Archiver/RecordingDescriptorPoller.cs @@ -136,7 +136,7 @@ public virtual ControlledFragmentHandlerAction OnFragment(IDirectBuffer buffer, if (ControlResponseCode.ERROR == code) { - throw new System.InvalidOperationException("response for expectedCorrelationId=" + expectedCorrelationId + ", error: " + controlResponseDecoder.ErrorMessage()); + throw new ArchiveException("response for expectedCorrelationId=" + expectedCorrelationId + ", error: " + controlResponseDecoder.ErrorMessage()); } break; @@ -161,7 +161,7 @@ public virtual ControlledFragmentHandlerAction OnFragment(IDirectBuffer buffer, break; default: - throw new System.InvalidOperationException("unknown templateId: " + templateId); + throw new ArchiveException("unknown templateId: " + templateId); } return ControlledFragmentHandlerAction.CONTINUE; diff --git a/src/Adaptive.Archiver/RecordingEventsAdapter.cs b/src/Adaptive.Archiver/RecordingEventsAdapter.cs index fd8a435c..d59fcfbe 100644 --- a/src/Adaptive.Archiver/RecordingEventsAdapter.cs +++ b/src/Adaptive.Archiver/RecordingEventsAdapter.cs @@ -1,5 +1,4 @@ -using System; -using Adaptive.Aeron; +using Adaptive.Aeron; using Adaptive.Aeron.LogBuffer; using Adaptive.Agrona; using Adaptive.Archiver.Codecs; @@ -92,7 +91,7 @@ public virtual void OnFragment(IDirectBuffer buffer, int offset, int length, Hea break; default: - throw new InvalidOperationException("unknown templateId: " + templateId); + throw new ArchiveException("unknown templateId: " + templateId); } } } diff --git a/src/Adaptive.Archiver/RecordingEventsPoller.cs b/src/Adaptive.Archiver/RecordingEventsPoller.cs index 5a00734e..7a2f546b 100644 --- a/src/Adaptive.Archiver/RecordingEventsPoller.cs +++ b/src/Adaptive.Archiver/RecordingEventsPoller.cs @@ -40,7 +40,7 @@ public RecordingEventsPoller(Subscription subscription) /// the number of fragments read during the operation. Zero if no events are available. public virtual int Poll() { - templateId = -1; + templateId = Aeron.Aeron.NULL_VALUE; pollComplete = false; return subscription.Poll(this, 1); @@ -113,7 +113,7 @@ public virtual void OnFragment(IDirectBuffer buffer, int offset, int length, Hea recordingId = recordingStartedDecoder.RecordingId(); recordingStartPosition = recordingStartedDecoder.StartPosition(); recordingPosition = recordingStartPosition; - recordingStopPosition = -1; + recordingStopPosition = Aeron.Aeron.NULL_VALUE; break; case RecordingProgressDecoder.TEMPLATE_ID: @@ -122,7 +122,7 @@ public virtual void OnFragment(IDirectBuffer buffer, int offset, int length, Hea recordingId = recordingProgressDecoder.RecordingId(); recordingStartPosition = recordingProgressDecoder.StartPosition(); recordingPosition = recordingProgressDecoder.Position(); - recordingStopPosition = -1; + recordingStopPosition = Aeron.Aeron.NULL_VALUE; break; case RecordingStoppedDecoder.TEMPLATE_ID: @@ -135,7 +135,7 @@ public virtual void OnFragment(IDirectBuffer buffer, int offset, int length, Hea break; default: - throw new System.InvalidOperationException("unknown templateId: " + templateId); + throw new ArchiveException("unknown templateId: " + templateId); } pollComplete = true; diff --git a/src/Adaptive.Archiver/RecordingPos.cs b/src/Adaptive.Archiver/RecordingPos.cs index f0873b55..7c6c26a9 100644 --- a/src/Adaptive.Archiver/RecordingPos.cs +++ b/src/Adaptive.Archiver/RecordingPos.cs @@ -16,16 +16,8 @@ namespace Adaptive.Archiver /// | Recording ID | /// | | /// +---------------------------------------------------------------+ - /// | Control Session ID | - /// | | - /// +---------------------------------------------------------------+ - /// | Correlation ID | - /// | | - /// +---------------------------------------------------------------+ /// | Session ID | /// +---------------------------------------------------------------+ - /// | Stream ID | - /// +---------------------------------------------------------------+ /// /// public class RecordingPos @@ -38,7 +30,7 @@ public class RecordingPos /// /// Represents a null recording id when not found. /// - public const long NULL_RECORDING_ID = -1L; + public const long NULL_RECORDING_ID = Aeron.Aeron.NULL_VALUE; /// /// Human readable name for the counter. @@ -46,21 +38,14 @@ public class RecordingPos public const string NAME = "rec-pos"; public const int RECORDING_ID_OFFSET = 0; - public static readonly int CONTROL_SESSION_ID_OFFSET = RECORDING_ID_OFFSET + BitUtil.SIZE_OF_LONG; - public static readonly int CORRELATION_ID_OFFSET = CONTROL_SESSION_ID_OFFSET + BitUtil.SIZE_OF_LONG; - public static readonly int SESSION_ID_OFFSET = CORRELATION_ID_OFFSET + BitUtil.SIZE_OF_LONG; - public static readonly int STREAM_ID_OFFSET = SESSION_ID_OFFSET + BitUtil.SIZE_OF_INT; - public static readonly int KEY_LENGTH = STREAM_ID_OFFSET + BitUtil.SIZE_OF_INT; + public static readonly int SESSION_ID_OFFSET = RECORDING_ID_OFFSET + BitUtil.SIZE_OF_LONG; + public static readonly int KEY_LENGTH = SESSION_ID_OFFSET + BitUtil.SIZE_OF_INT; public static Counter Allocate(Aeron.Aeron aeron, UnsafeBuffer tempBuffer, long recordingId, - long controlSessionId, - long correlationId, int sessionId, int streamId, string strippedChannel) + 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 + ": "); @@ -104,35 +89,6 @@ public static int FindCounterIdByRecording(CountersReader countersReader, long r return CountersReader.NULL_COUNTER_ID; } - /// - /// Count the number of counters for a given session. It is possible for different recording to exist on the - /// same session if there are images under subscriptions with different channel and stream id. - /// - /// to search within. - /// to search for. - /// the count of recordings matching a session id. - public static int CountBySession(CountersReader countersReader, int sessionId) - { - int count = 0; - IDirectBuffer buffer = countersReader.MetaDataBuffer; - - for (int i = 0, size = countersReader.MaxCounterId; i < size; i++) - { - if (countersReader.GetCounterState(i) == CountersReader.RECORD_ALLOCATED) - { - int recordOffset = CountersReader.MetaDataOffset(i); - - if (buffer.GetInt(recordOffset + CountersReader.TYPE_ID_OFFSET) == RECORDING_POSITION_TYPE_ID && - buffer.GetInt(recordOffset + CountersReader.KEY_OFFSET + SESSION_ID_OFFSET) == sessionId) - { - ++count; - } - } - } - - return count; - } - /// /// Find the active counter id for a stream based on the session id. /// diff --git a/src/Adaptive.Archiver/aeron-archive-codecs.xml b/src/Adaptive.Archiver/aeron-archive-codecs.xml index 53d474a6..d477323c 100644 --- a/src/Adaptive.Archiver/aeron-archive-codecs.xml +++ b/src/Adaptive.Archiver/aeron-archive-codecs.xml @@ -43,7 +43,7 @@ + description="Relevant identity of an object, e.g. recordingId if RECORDING_UNKNOWN, or error code"/> netstandard2.0;net45 true Aeron.Cluster - 1.9.4 + 1.10.0 Adaptive Financial Consulting Ltd. Adaptive Financial Consulting Ltd. Clustering libraries over the Aeron transport diff --git a/src/Adaptive.Cluster/Client/AeronCluster.cs b/src/Adaptive.Cluster/Client/AeronCluster.cs index 24fd9dc1..ee619876 100644 --- a/src/Adaptive.Cluster/Client/AeronCluster.cs +++ b/src/Adaptive.Cluster/Client/AeronCluster.cs @@ -1,6 +1,7 @@ using System; -using System.Security.Authentication; +using System.Collections.Generic; using Adaptive.Aeron; +using Adaptive.Aeron.Exceptions; using Adaptive.Aeron.LogBuffer; using Adaptive.Agrona; using Adaptive.Agrona.Concurrent; @@ -14,26 +15,88 @@ namespace Adaptive.Cluster.Client /// A client will connect to open a session and then offer ingress messages which are replicated to clustered service /// for reliability. If the clustered service responds then these response messages and events come back via the egress /// stream. + /// + /// Note: Instances of this class are not threadsafe. /// /// public sealed class AeronCluster : IDisposable { private const int SEND_ATTEMPTS = 3; - private const int FRAGMENT_LIMIT = 1; + private const int CONNECT_FRAGMENT_LIMIT = 1; + private const int SESSION_FRAGMENT_LIMIT = 10; + private long _lastCorrelationId = Aeron.Aeron.NULL_VALUE; private readonly long _clusterSessionId; + private int _leaderMemberId = Aeron.Aeron.NULL_VALUE; private readonly bool _isUnicast; private readonly Context _ctx; private readonly Aeron.Aeron _aeron; private readonly Subscription _subscription; - private readonly Publication _publication; + private Publication _publication; private readonly INanoClock _nanoClock; - private readonly ILock _lock; private readonly IIdleStrategy _idleStrategy; + + private readonly Dictionary _endpointByMemberIdMap = new Dictionary(); private readonly BufferClaim _bufferClaim = new BufferClaim(); private readonly MessageHeaderEncoder _messageHeaderEncoder = new MessageHeaderEncoder(); private readonly SessionKeepAliveRequestEncoder _keepAliveRequestEncoder = new SessionKeepAliveRequestEncoder(); + private readonly SessionHeaderEncoder _sessionHeaderEncoder = new SessionHeaderEncoder(); + private readonly DirectBufferVector[] _vectors = new DirectBufferVector[2]; + private readonly DirectBufferVector _messageBuffer = new DirectBufferVector(); + private readonly FragmentAssembler _fragmentAssembler; + private readonly Poller _poller; + + private class Poller : IFragmentHandler + { + private readonly MessageHeaderDecoder _messageHeaderDecoder = new MessageHeaderDecoder(); + private readonly SessionHeaderDecoder _sessionHeaderDecoder = new SessionHeaderDecoder(); + private readonly NewLeaderEventDecoder _newLeaderEventDecoder = new NewLeaderEventDecoder(); + + private readonly ISessionMessageListener _sessionMessageListener; + private readonly long _clusterSessionId; + private readonly AeronCluster _cluster; + + public Poller(ISessionMessageListener sessionMessageListener, long clusterSessionId, AeronCluster cluster) + { + _sessionMessageListener = sessionMessageListener; + _clusterSessionId = clusterSessionId; + _cluster = cluster; + } + + public void OnFragment(IDirectBuffer buffer, int offset, int length, Header header) + { + _messageHeaderDecoder.Wrap(buffer, offset); + + int templateId = _messageHeaderDecoder.TemplateId(); + if (SessionHeaderDecoder.TEMPLATE_ID == templateId) + { + _sessionHeaderDecoder.Wrap(buffer, offset + MessageHeaderDecoder.ENCODED_LENGTH, + _messageHeaderDecoder.BlockLength(), _messageHeaderDecoder.Version()); + + long sessionId = _sessionHeaderDecoder.ClusterSessionId(); + if (sessionId == _clusterSessionId) + { + _sessionMessageListener.OnMessage(_sessionHeaderDecoder.CorrelationId(), sessionId, + _sessionHeaderDecoder.Timestamp(), buffer, offset + SessionDecorator.SESSION_HEADER_LENGTH, + length - SessionDecorator.SESSION_HEADER_LENGTH, header); + } + } + else if (NewLeaderEventDecoder.TEMPLATE_ID == templateId) + { + _newLeaderEventDecoder.Wrap(buffer, offset + MessageHeaderDecoder.ENCODED_LENGTH, + _messageHeaderDecoder.BlockLength(), _messageHeaderDecoder.Version()); + + long sessionId = _newLeaderEventDecoder.ClusterSessionId(); + if (sessionId == _clusterSessionId) + { + _cluster.OnNewLeader(sessionId, _newLeaderEventDecoder.LeaderMemberId(), + _newLeaderEventDecoder.MemberEndpoints()); + } + } + } + } + /// /// Connect to the cluster using default configuration. /// @@ -57,32 +120,42 @@ private AeronCluster(Context ctx) { _ctx = ctx; + Subscription subscription = null; - Publication publication = null; try { ctx.Conclude(); _aeron = ctx.Aeron(); - _lock = ctx.Lock(); _idleStrategy = ctx.IdleStrategy(); _nanoClock = _aeron.Ctx().NanoClock(); _isUnicast = ctx.ClusterMemberEndpoints() != null; + UpdateMemberEndpoints(ctx.ClusterMemberEndpoints()); subscription = _aeron.AddSubscription(ctx.EgressChannel(), ctx.EgressStreamId()); _subscription = subscription; - - publication = ConnectToCluster(); - _publication = publication; + _publication = ConnectToCluster(); _clusterSessionId = OpenSession(); + + UnsafeBuffer headerBuffer = new UnsafeBuffer(new byte[SessionDecorator.SESSION_HEADER_LENGTH]); + _sessionHeaderEncoder + .WrapAndApplyHeader(headerBuffer, 0, _messageHeaderEncoder) + .ClusterSessionId(_clusterSessionId) + .Timestamp(Aeron.Aeron.NULL_VALUE); + + _vectors[0] = new DirectBufferVector(headerBuffer, 0, SessionDecorator.SESSION_HEADER_LENGTH); + _vectors[1] = _messageBuffer; + + _poller = new Poller(ctx.SessionMessageListener(), _clusterSessionId, this); + _fragmentAssembler = new FragmentAssembler(_poller); } catch (Exception) { if (!ctx.OwnsAeronClient()) { - CloseHelper.QuietDispose(publication); + CloseHelper.QuietDispose(_publication); CloseHelper.QuietDispose(subscription); } @@ -96,26 +169,18 @@ private AeronCluster(Context ctx) /// public void Dispose() { - _lock.Lock(); - try + if (null != _publication && _publication.IsConnected) { - if (_publication.IsConnected) - { - CloseSession(); - } - - if (!_ctx.OwnsAeronClient()) - { - _subscription.Dispose(); - _publication.Dispose(); - } - - _ctx.Dispose(); + CloseSession(); } - finally + + if (!_ctx.OwnsAeronClient()) { - _lock.Unlock(); + _subscription.Dispose(); + _publication?.Dispose(); } + + _ctx.Dispose(); } /// @@ -136,6 +201,36 @@ public long ClusterSessionId() return _clusterSessionId; } + /// + /// Get the current leader member id for the cluster. + /// + /// the current leader member id for the cluster. + public int LeaderMemberId() + { + return _leaderMemberId; + } + + /// + /// Get the last correlation id generated for this session. Starts with . + /// + /// the last correlation id generated for this session. + /// + public long LastCorrelationId() + { + return _lastCorrelationId; + } + + /// + /// Generate a new correlation id to be used for this session. This is not threadsafe. If you require a threadsafe + /// correlation id generation then use . + /// + /// a new correlation id to be used for this session. + /// + public long NextCorrelationId() + { + return ++_lastCorrelationId; + } + /// /// Get the raw for sending to the cluster. /// @@ -162,47 +257,127 @@ public Subscription EgressSubscription() return _subscription; } + /// + /// Non-blocking publish of a partial buffer containing a message plus session header to a cluster. + /// + /// This version of the method will set the timestamp value in the header to zero. + /// + /// + /// + /// to be used to identify the message to the cluster. + /// containing message. + /// offset in the buffer at which the encoded message begins. + /// in bytes of the encoded message. + /// the same as . + public long Offer(long correlationId, IDirectBuffer buffer, int offset, int length) + { + _sessionHeaderEncoder.CorrelationId(correlationId); + _messageBuffer.Reset(buffer, offset, length); + + return _publication.Offer(_vectors); + } + /// /// Send a keep alive message to the cluster to keep this session open. /// /// true if successfully sent otherwise false. public bool SendKeepAlive() { - _lock.Lock(); - try + _idleStrategy.Reset(); + int length = MessageHeaderEncoder.ENCODED_LENGTH + SessionKeepAliveRequestEncoder.BLOCK_LENGTH; + int attempts = SEND_ATTEMPTS; + + while (true) { - _idleStrategy.Reset(); - int length = MessageHeaderEncoder.ENCODED_LENGTH + SessionKeepAliveRequestEncoder.BLOCK_LENGTH; - int attempts = SEND_ATTEMPTS; + long result = _publication.TryClaim(length, _bufferClaim); - while (true) + if (result > 0) { - long result = _publication.TryClaim(length, _bufferClaim); + _keepAliveRequestEncoder + .WrapAndApplyHeader(_bufferClaim.Buffer, _bufferClaim.Offset, _messageHeaderEncoder) + .CorrelationId(Aeron.Aeron.NULL_VALUE) + .ClusterSessionId(_clusterSessionId); - if (result > 0) - { - _keepAliveRequestEncoder.WrapAndApplyHeader(_bufferClaim.Buffer, _bufferClaim.Offset, _messageHeaderEncoder).CorrelationId(0L).ClusterSessionId(_clusterSessionId); + _bufferClaim.Commit(); - _bufferClaim.Commit(); + return true; + } - return true; - } + CheckResult(result); - CheckResult(result); + if (--attempts <= 0) + { + break; + } - if (--attempts <= 0) - { - break; - } + _idleStrategy.Idle(); + } - _idleStrategy.Idle(); - } + return false; + } - return false; + /// + /// Poll the for session messages which are dispatched to + /// . + /// + /// Note: if is not set then a could + /// result. + /// + /// + /// + /// the number of fragments processed. + public int PollEgress() + { + return _subscription.Poll(_fragmentAssembler, SESSION_FRAGMENT_LIMIT); + } + + /// + /// To be called when a new leader event is delivered. This method needs to be called when using the + /// or rather than method. + /// + /// which must match . + /// which has become the new leader. + /// comma separated list of cluster members endpoints to connect to with the leader first. + public void OnNewLeader(long clusterSessionId, int leaderMemberId, string memberEndpoints) + { + if (clusterSessionId != _clusterSessionId) + { + throw new ClusterException("invalid clusterSessionId=" + clusterSessionId + " expected " + + _clusterSessionId); } - finally + + _leaderMemberId = leaderMemberId; + + if (_isUnicast) { - _lock.Unlock(); + _publication?.Dispose(); + _fragmentAssembler.Clear(); + UpdateMemberEndpoints(memberEndpoints); + + ChannelUri channelUri = ChannelUri.Parse(_ctx.IngressChannel()); + channelUri.Put(Aeron.Aeron.Context.ENDPOINT_PARAM_NAME, _endpointByMemberIdMap[leaderMemberId]); + _publication = AddIngressPublication(channelUri.ToString(), _ctx.IngressStreamId()); + } + } + + private void UpdateMemberEndpoints(string memberEndpoints) + { + _endpointByMemberIdMap.Clear(); + + if (null != memberEndpoints) + { + foreach (String member in memberEndpoints.Split(',')) + { + int separatorIndex = member.IndexOf('='); + if (-1 == separatorIndex) + { + throw new ConfigurationException("invalid format - member missing '=' separator: " + + memberEndpoints); + } + + int memberId = int.Parse(member.Substring(0, separatorIndex)); + _endpointByMemberIdMap[memberId] = member.Substring(separatorIndex + 1); + } } } @@ -219,7 +394,9 @@ private void CloseSession() if (result > 0) { - sessionCloseRequestEncoder.WrapAndApplyHeader(_bufferClaim.Buffer, _bufferClaim.Offset, _messageHeaderEncoder).ClusterSessionId(_clusterSessionId); + sessionCloseRequestEncoder + .WrapAndApplyHeader(_bufferClaim.Buffer, _bufferClaim.Offset, _messageHeaderEncoder) + .ClusterSessionId(_clusterSessionId); _bufferClaim.Commit(); break; @@ -246,17 +423,16 @@ private Publication ConnectToCluster() if (_isUnicast) { ChannelUri channelUri = ChannelUri.Parse(ingressChannel); - string[] memberEndpoints = _ctx.ClusterMemberEndpoints(); - int memberCount = memberEndpoints.Length; + int memberCount = _endpointByMemberIdMap.Count; Publication[] publications = new Publication[memberCount]; - for (int i = 0; i < memberCount; i++) + foreach (var entry in _endpointByMemberIdMap) { - channelUri.Put(Aeron.Aeron.Context.ENDPOINT_PARAM_NAME, memberEndpoints[i]); + channelUri.Put(Aeron.Aeron.Context.ENDPOINT_PARAM_NAME, entry.Value); string channel = channelUri.ToString(); - publications[i] = AddIngressPublication(channel, ingressStreamId); + publications[entry.Key] = AddIngressPublication(channel, ingressStreamId); } - + int connectedIndex = -1; while (true) { @@ -279,7 +455,6 @@ private Publication ConnectToCluster() } else { - publications[i]?.Dispose(); } } @@ -293,7 +468,7 @@ private Publication ConnectToCluster() { CloseHelper.QuietDispose(publications[i]); } - + throw new TimeoutException("awaiting connection to cluster"); } @@ -310,7 +485,7 @@ private Publication ConnectToCluster() if (_nanoClock.NanoTime() > deadlineNs) { CloseHelper.QuietDispose(publication); - + throw new TimeoutException("awaiting connection to cluster"); } @@ -337,7 +512,7 @@ private long OpenSession() { long deadlineNs = _nanoClock.NanoTime() + _ctx.MessageTimeoutNs(); long correlationId = SendConnectRequest(_ctx.CredentialsSupplier().EncodedCredentials(), deadlineNs); - EgressPoller poller = new EgressPoller(_subscription, FRAGMENT_LIMIT); + EgressPoller poller = new EgressPoller(_subscription, CONNECT_FRAGMENT_LIMIT); while (true) { @@ -348,13 +523,15 @@ private long OpenSession() if (poller.IsChallenged()) { byte[] encodedCredentials = _ctx.CredentialsSupplier().OnChallenge(poller.EncodedChallenge()); - correlationId = SendChallengeResponse(poller.ClusterSessionId(), encodedCredentials, deadlineNs); + correlationId = + SendChallengeResponse(poller.ClusterSessionId(), encodedCredentials, deadlineNs); continue; } switch (poller.EventCode()) { case EventCode.OK: + _leaderMemberId = poller.LeaderMemberId(); return poller.ClusterSessionId(); case EventCode.ERROR: @@ -384,13 +561,13 @@ private void PollNextResponse(long deadlineNs, long correlationId, EgressPoller private long SendConnectRequest(byte[] encodedCredentials, long deadlineNs) { - long correlationId = _aeron.NextCorrelationId(); + _lastCorrelationId = _aeron.NextCorrelationId(); SessionConnectRequestEncoder sessionConnectRequestEncoder = new SessionConnectRequestEncoder(); - int length = MessageHeaderEncoder.ENCODED_LENGTH + - SessionConnectRequestEncoder.BLOCK_LENGTH + - SessionConnectRequestEncoder.ResponseChannelHeaderLength() + - _ctx.EgressChannel().Length + + int length = MessageHeaderEncoder.ENCODED_LENGTH + + SessionConnectRequestEncoder.BLOCK_LENGTH + + SessionConnectRequestEncoder.ResponseChannelHeaderLength() + + _ctx.EgressChannel().Length + SessionConnectRequestEncoder.EncodedCredentialsHeaderLength() + encodedCredentials.Length; _idleStrategy.Reset(); @@ -400,8 +577,9 @@ private long SendConnectRequest(byte[] encodedCredentials, long deadlineNs) long result = _publication.TryClaim(length, _bufferClaim); if (result > 0) { - sessionConnectRequestEncoder.WrapAndApplyHeader(_bufferClaim.Buffer, _bufferClaim.Offset, _messageHeaderEncoder) - .CorrelationId(correlationId) + sessionConnectRequestEncoder + .WrapAndApplyHeader(_bufferClaim.Buffer, _bufferClaim.Offset, _messageHeaderEncoder) + .CorrelationId(_lastCorrelationId) .ResponseStreamId(_ctx.EgressStreamId()) .ResponseChannel(_ctx.EgressChannel()) .PutEncodedCredentials(encodedCredentials, 0, encodedCredentials.Length); @@ -413,7 +591,7 @@ private long SendConnectRequest(byte[] encodedCredentials, long deadlineNs) if (Publication.CLOSED == result) { - throw new InvalidOperationException("unexpected close from cluster"); + throw new ClusterException("unexpected close from cluster"); } if (_nanoClock.NanoTime() > deadlineNs) @@ -424,17 +602,17 @@ private long SendConnectRequest(byte[] encodedCredentials, long deadlineNs) _idleStrategy.Idle(); } - return correlationId; + return _lastCorrelationId; } private long SendChallengeResponse(long sessionId, byte[] encodedCredentials, long deadlineNs) { - long correlationId = _aeron.NextCorrelationId(); + _lastCorrelationId = _aeron.NextCorrelationId(); ChallengeResponseEncoder challengeResponseEncoder = new ChallengeResponseEncoder(); - int length = MessageHeaderEncoder.ENCODED_LENGTH + - ChallengeResponseEncoder.BLOCK_LENGTH + - ChallengeResponseEncoder.EncodedCredentialsHeaderLength() + + int length = MessageHeaderEncoder.ENCODED_LENGTH + + ChallengeResponseEncoder.BLOCK_LENGTH + + ChallengeResponseEncoder.EncodedCredentialsHeaderLength() + encodedCredentials.Length; _idleStrategy.Reset(); @@ -446,7 +624,7 @@ private long SendChallengeResponse(long sessionId, byte[] encodedCredentials, lo { challengeResponseEncoder .WrapAndApplyHeader(_bufferClaim.Buffer, _bufferClaim.Offset, _messageHeaderEncoder) - .CorrelationId(correlationId) + .CorrelationId(_lastCorrelationId) .ClusterSessionId(sessionId) .PutEncodedCredentials(encodedCredentials, 0, encodedCredentials.Length); @@ -465,14 +643,15 @@ private long SendChallengeResponse(long sessionId, byte[] encodedCredentials, lo _idleStrategy.Idle(); } - return correlationId; + return _lastCorrelationId; } private static void CheckResult(long result) { - if (result == Publication.NOT_CONNECTED || result == Publication.CLOSED || result == Publication.MAX_POSITION_EXCEEDED) + if (result == Publication.NOT_CONNECTED || result == Publication.CLOSED || + result == Publication.MAX_POSITION_EXCEEDED) { - throw new InvalidOperationException("unexpected publication state: " + result); + throw new ClusterException("unexpected publication state: " + result); } } @@ -487,26 +666,30 @@ public class Configuration public const string MESSAGE_TIMEOUT_PROP_NAME = "aeron.cluster.message.timeout"; /// - /// Timeout when waiting on a message to be sent or received. Default to 5 seconds in nanoseconds. + /// Default timeout when waiting on a message to be sent or received. /// public static readonly long MESSAGE_TIMEOUT_DEFAULT_NS = 5000000000; /// - /// Property name for the comma separated list of cluster member endpoints for use with unicast. - /// + /// Property name for the comma separated list of cluster member endpoints for use with unicast. This is the + /// endpoint values which get substituted into the when using UDP unicast. + /// + /// 0=endpoint,1=endpoint,2=endpoint + /// /// Each member of the list will be substituted for the endpoint in the value. - /// + /// /// public const string CLUSTER_MEMBER_ENDPOINTS_PROP_NAME = "aeron.cluster.member.endpoints"; /// - /// Property name for the comma separated list of cluster member endpoints. + /// Default comma separated list of cluster member endpoints. /// public const string CLUSTER_MEMBER_ENDPOINTS_DEFAULT = null; /// /// Channel for sending messages to a cluster. Ideally this will be a multicast address otherwise unicast will - /// be required and the is used to substitute the endpoints. + /// be required and the is used to substitute the endpoints from + /// the list. /// public const string INGRESS_CHANNEL_PROP_NAME = "aeron.cluster.ingress.channel"; @@ -521,9 +704,9 @@ public class Configuration public const string INGRESS_STREAM_ID_PROP_NAME = "aeron.cluster.ingress.stream.id"; /// - /// Stream id within a channel for sending messages to a cluster. + /// Default stream id within a channel for sending messages to a cluster. /// - public const int INGRESS_STREAM_ID_DEFAULT = 1; + public const int INGRESS_STREAM_ID_DEFAULT = 101; /// /// Channel for receiving response messages from a cluster. @@ -541,9 +724,9 @@ public class Configuration public const string EGRESS_STREAM_ID_PROP_NAME = "aeron.archive.control.response.stream.id"; /// - /// Stream id within a channel for receiving messages from a cluster. + /// Default stream id within a channel for receiving messages from a cluster. /// - public const int EGRESS_STREAM_ID_DEFAULT = 2; + public const int EGRESS_STREAM_ID_DEFAULT = 102; /// /// The timeout in nanoseconds to wait for a message. @@ -561,11 +744,10 @@ public static long MessageTimeoutNs() /// /// or system property /// if set. - public static string[] ClusterMemberEndpoints() + public static string ClusterMemberEndpoints() { - string memberEndpoints = Config.GetProperty(CLUSTER_MEMBER_ENDPOINTS_PROP_NAME, CLUSTER_MEMBER_ENDPOINTS_DEFAULT); - - return memberEndpoints?.Split(','); + return + Config.GetProperty(CLUSTER_MEMBER_ENDPOINTS_PROP_NAME, CLUSTER_MEMBER_ENDPOINTS_DEFAULT); } /// @@ -618,19 +800,35 @@ public static int EgressStreamId() /// public class Context : IDisposable { + private class MissingSessionMessageListner : ISessionMessageListener + { + public void OnMessage( + long correlationId, + long clusterSessionId, + long timestamp, + IDirectBuffer buffer, + int offset, + int length, + Header header) + { + throw new ConfigurationException("sessionMessageListener must be specified on AeronCluster.Context"); + } + } + private long _messageTimeoutNs = Configuration.MessageTimeoutNs(); - private string[] _clusterMemberEndpoints = Configuration.ClusterMemberEndpoints(); + private string _clusterMemberEndpoints = Configuration.ClusterMemberEndpoints(); private string _ingressChannel = Configuration.IngressChannel(); private int _ingressStreamId = Configuration.IngressStreamId(); private string _egressChannel = Configuration.EgressChannel(); private int _egressStreamId = Configuration.EgressStreamId(); private IIdleStrategy _idleStrategy; - private ILock _lock; private string _aeronDirectoryName = Adaptive.Aeron.Aeron.Context.GetAeronDirectoryName(); private Aeron.Aeron _aeron; private ICredentialsSupplier _credentialsSupplier; private bool _ownsAeronClient = false; private bool _isIngressExclusive = true; + private ErrorHandler _errorHandler = Adaptive.Aeron.Aeron.DEFAULT_ERROR_HANDLER; + private ISessionMessageListener _sessionMessageListener; /// /// Perform a shallow copy of the object. @@ -638,14 +836,17 @@ public class Context : IDisposable /// a shall copy of the object. public Context Clone() { - return (Context)MemberwiseClone(); + return (Context) MemberwiseClone(); } - + public void Conclude() { if (null == _aeron) { - _aeron = Adaptive.Aeron.Aeron.Connect(new Aeron.Aeron.Context().AeronDirectoryName(_aeronDirectoryName)); + _aeron = Adaptive.Aeron.Aeron.Connect( + new Aeron.Aeron.Context() + .AeronDirectoryName(_aeronDirectoryName) + .ErrorHandler(_errorHandler)); _ownsAeronClient = true; } @@ -654,15 +855,15 @@ public void Conclude() _idleStrategy = new BackoffIdleStrategy(1, 10, 1, 1); } - if (null == _lock) - { - _lock = new ReentrantLock(); - } - if (null == _credentialsSupplier) { _credentialsSupplier = new NullCredentialsSupplier(); } + + if (null == _sessionMessageListener) + { + _sessionMessageListener = new MissingSessionMessageListner(); + } } /// @@ -688,29 +889,39 @@ public long MessageTimeoutNs() } /// - /// The endpoints representing members for use with unicast. A null value can be used when multicast. + /// The endpoints representing members for use with unicast to be substituted into the + /// for endpoints. A null value can be used when multicast where the contains the + /// multicast endpoint. /// /// which are all candidates to be leader. /// this for a fluent API. /// - public Context ClusterMemberEndpoints(params string[] clusterMembers) + public Context ClusterMemberEndpoints(string clusterMembers) { _clusterMemberEndpoints = clusterMembers; return this; } /// - /// The endpoints representing members for use with unicast. A null value can be used when multicast. + /// The endpoints representing members for use with unicast to be substituted into the + /// for endpoints. A null value can be used when multicast where the contains the + /// multicast endpoint. /// /// members of the cluster which are all candidates to be leader. /// - public string[] ClusterMemberEndpoints() + public string ClusterMemberEndpoints() { return _clusterMemberEndpoints; } /// /// Set the channel parameter for the ingress channel. + /// + /// The endpoints representing members for use with unicast are substituted from the + /// for endpoints. A null value can be used when multicast + /// where this contains the multicast endpoint. + /// + /// /// /// parameter for the ingress channel. /// this for a fluent API. @@ -722,7 +933,12 @@ public Context IngressChannel(string channel) } /// - /// Get the channel parameter for the ingress channel. + /// Set the channel parameter for the ingress channel. + /// + /// The endpoints representing members for use with unicast are substituted from the + /// for endpoints. A null value can be used when multicast + /// where this contains the multicast endpoint. + /// /// /// the channel parameter for the ingress channel. /// @@ -888,31 +1104,6 @@ public bool OwnsAeronClient() return _ownsAeronClient; } - /// - /// The that is used to provide mutual exclusion in the client. - /// - /// If the is used from only a single thread then the lock can be set to - /// to elide the lock overhead. - /// - /// - /// - /// that is used to provide mutual exclusion in the client. - /// this for a fluent API. - public Context Lock(ILock @lock) - { - _lock = @lock; - return this; - } - - /// - /// Get the that is used to provide mutual exclusion in the client. - /// - /// the that is used to provide mutual exclusion in the client. - public ILock Lock() - { - return _lock; - } - /// /// Is ingress to the cluster exclusively from a single thread for this client? /// @@ -952,11 +1143,55 @@ public Context CredentialsSupplier(ICredentialsSupplier credentialsSupplier) _credentialsSupplier = credentialsSupplier; return this; } + + /// + /// Get the to be used for handling any exceptions. + /// + /// The to be used for handling any exceptions. + public ErrorHandler ErrorHandler() + { + return _errorHandler; + } + + /// + /// Set the to be used for handling any exceptions. + /// + /// Method to handle objects of type Throwable. + /// this for fluent API. + public virtual Context ErrorHandler(ErrorHandler errorHandler) + { + _errorHandler = errorHandler; + return this; + } + + /// + /// Get the function that will be called when polling for egress via + /// . + /// + /// the function that will be called when polling for egress via + /// . + public ISessionMessageListener SessionMessageListener() + { + return _sessionMessageListener; + } + + /// + /// Get the function that will be called when polling for egress via + /// . + /// + /// function that will be called when polling for egress via . + /// this for a fluent API. + public Context SessionMessageListener(ISessionMessageListener listener) + { + _sessionMessageListener = listener; + return this; + } + /// /// Close the context and free applicable resources. /// - /// If the is true then the client will be closed. + /// If is true then the client will be closed. /// /// public void Dispose() diff --git a/src/Adaptive.Cluster/Client/AuthenticationException.cs b/src/Adaptive.Cluster/Client/AuthenticationException.cs new file mode 100644 index 00000000..bd646b4b --- /dev/null +++ b/src/Adaptive.Cluster/Client/AuthenticationException.cs @@ -0,0 +1,28 @@ +using System; +using System.Runtime.Serialization; +using Adaptive.Aeron.Exceptions; + +namespace Adaptive.Cluster.Client +{ + /// + /// Used to indicated a failed authentication attempt when connecting to the cluster. + /// + public class AuthenticationException : AeronException + { + public AuthenticationException() + { + } + + protected AuthenticationException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + public AuthenticationException(string message) : base(message) + { + } + + public AuthenticationException(string message, Exception innerException) : base(message, innerException) + { + } + } +} \ No newline at end of file diff --git a/src/Adaptive.Cluster/Client/ClusterException.cs b/src/Adaptive.Cluster/Client/ClusterException.cs new file mode 100644 index 00000000..3148b623 --- /dev/null +++ b/src/Adaptive.Cluster/Client/ClusterException.cs @@ -0,0 +1,25 @@ +using System; +using System.Runtime.Serialization; +using Adaptive.Aeron.Exceptions; + +namespace Adaptive.Cluster.Client +{ + public class ClusterException : AeronException + { + public ClusterException() + { + } + + protected ClusterException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + public ClusterException(string message) : base(message) + { + } + + public ClusterException(string message, Exception innerException) : base(message, innerException) + { + } + } +} \ No newline at end of file diff --git a/src/Adaptive.Cluster/Client/EgressAdapter.cs b/src/Adaptive.Cluster/Client/EgressAdapter.cs index 917a3eb0..de4a7af8 100644 --- a/src/Adaptive.Cluster/Client/EgressAdapter.cs +++ b/src/Adaptive.Cluster/Client/EgressAdapter.cs @@ -48,6 +48,29 @@ public void OnFragment(IDirectBuffer buffer, int offset, int length, Header head int templateId = _messageHeaderDecoder.TemplateId(); switch (templateId) { + case SessionHeaderDecoder.TEMPLATE_ID: + { + _sessionHeaderDecoder.Wrap( + buffer, + offset + MessageHeaderDecoder.ENCODED_LENGTH, + _messageHeaderDecoder.BlockLength(), + _messageHeaderDecoder.Version()); + + var sessionId = _sessionHeaderDecoder.ClusterSessionId(); + if (sessionId == _clusterSessionId) + { + _listener.OnMessage( + _sessionHeaderDecoder.CorrelationId(), + _sessionHeaderDecoder.ClusterSessionId(), + _sessionHeaderDecoder.Timestamp(), + buffer, + offset + SESSION_HEADER_LENGTH, + length - SESSION_HEADER_LENGTH, + header); + } + break; + } + case SessionEventDecoder.TEMPLATE_ID: { _sessionEventDecoder.Wrap( @@ -62,7 +85,8 @@ public void OnFragment(IDirectBuffer buffer, int offset, int length, Header head _listener.SessionEvent( _sessionEventDecoder.CorrelationId(), - _sessionEventDecoder.ClusterSessionId(), + sessionId, + _sessionEventDecoder.LeaderMemberId(), _sessionEventDecoder.Code(), _sessionEventDecoder.Detail()); } @@ -82,11 +106,7 @@ public void OnFragment(IDirectBuffer buffer, int offset, int length, Header head if (sessionId == _clusterSessionId) { _listener.NewLeader( - _newLeaderEventDecoder.LastCorrelationId(), - _newLeaderEventDecoder.ClusterSessionId(), - _newLeaderEventDecoder.LastMessageTimestamp(), - _newLeaderEventDecoder.LeadershipTimestamp(), - _newLeaderEventDecoder.LeadershipTermId(), + sessionId, _newLeaderEventDecoder.LeaderMemberId(), _newLeaderEventDecoder.MemberEndpoints()); } @@ -94,34 +114,11 @@ public void OnFragment(IDirectBuffer buffer, int offset, int length, Header head break; } - case SessionHeaderDecoder.TEMPLATE_ID: - { - _sessionHeaderDecoder.Wrap( - buffer, - offset + MessageHeaderDecoder.ENCODED_LENGTH, - _messageHeaderDecoder.BlockLength(), - _messageHeaderDecoder.Version()); - - var sessionId = _sessionHeaderDecoder.ClusterSessionId(); - if (sessionId == _clusterSessionId) - { - _listener.OnMessage( - _sessionHeaderDecoder.CorrelationId(), - _sessionHeaderDecoder.ClusterSessionId(), - _sessionHeaderDecoder.Timestamp(), - buffer, - offset + SESSION_HEADER_LENGTH, - length - SESSION_HEADER_LENGTH, - header); - } - break; - } - case ChallengeDecoder.TEMPLATE_ID: break; default: - throw new InvalidOperationException("unknown templateId: " + templateId); + throw new ClusterException("unknown templateId: " + templateId); } } } diff --git a/src/Adaptive.Cluster/Client/EgressListener.cs b/src/Adaptive.Cluster/Client/EgressListener.cs deleted file mode 100644 index cd18bd84..00000000 --- a/src/Adaptive.Cluster/Client/EgressListener.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Adaptive.Aeron.LogBuffer; -using Adaptive.Agrona; -using Adaptive.Cluster.Codecs; - -namespace Adaptive.Cluster.Client -{ - public interface IEgressListener - { - void SessionEvent( - long correlationId, - long clusterSessionId, - EventCode code, - string detail); - - void NewLeader( - long correlationId, - long clusterSessionId, - long lastMessageTimestamp, - long leadershipTimestamp, - long leadershipTermId, - int leaderMemberId, - string memberEndpoints); - - void OnMessage( - long correlationId, - long clusterSessionId, - long timestamp, - IDirectBuffer buffer, - int offset, - int length, - Header header); - } -} \ No newline at end of file diff --git a/src/Adaptive.Cluster/Client/EgressPoller.cs b/src/Adaptive.Cluster/Client/EgressPoller.cs index 3c289ec6..7f940876 100644 --- a/src/Adaptive.Cluster/Client/EgressPoller.cs +++ b/src/Adaptive.Cluster/Client/EgressPoller.cs @@ -16,9 +16,10 @@ public class EgressPoller : IControlledFragmentHandler private readonly ChallengeDecoder challengeDecoder = new ChallengeDecoder(); private readonly ControlledFragmentAssembler fragmentAssembler; private readonly Subscription subscription; - private long clusterSessionId = -1; - private long correlationId = -1; - private int templateId = -1; + private long clusterSessionId = Aeron.Aeron.NULL_VALUE; + private long correlationId = Aeron.Aeron.NULL_VALUE; + private int templateId = Aeron.Aeron.NULL_VALUE; + private int leaderMemberId = Aeron.Aeron.NULL_VALUE; private bool pollComplete; private EventCode eventCode; private string detail = ""; @@ -51,22 +52,31 @@ public int TemplateId() } /// - /// Cluster session id of the last polled event or -1 if poll returned nothing. + /// Cluster session id of the last polled event or if poll returned nothing. /// - /// cluster session id of the last polled event or -1 if unrecognised template. + /// cluster session id of the last polled event or if unrecognised template. public long ClusterSessionId() { return clusterSessionId; } /// - /// Correlation id of the last polled event or -1 if poll returned nothing. + /// Correlation id of the last polled event or if poll returned nothing. /// - /// correlation id of the last polled event or -1 if unrecognised template. + /// correlation id of the last polled event or if unrecognised template. public long CorrelationId() { return correlationId; } + + /// + /// Leader cluster member id of the last polled event or if poll returned nothing. + /// + /// leader cluster member id of the last polled event or if poll returned nothing. + public int LeaderMemberId() + { + return leaderMemberId; + } /// /// Get the event code returned from the last session event. @@ -115,9 +125,10 @@ public bool IsChallenged() public int Poll() { - clusterSessionId = -1; - correlationId = -1; - templateId = -1; + clusterSessionId = Aeron.Aeron.NULL_VALUE; + correlationId = Aeron.Aeron.NULL_VALUE; + templateId = Aeron.Aeron.NULL_VALUE; + leaderMemberId = Aeron.Aeron.NULL_VALUE; eventCode = Codecs.EventCode.NULL_VALUE; detail = ""; encodedChallenge = null; @@ -139,6 +150,7 @@ public ControlledFragmentHandlerAction OnFragment(IDirectBuffer buffer, int offs clusterSessionId = sessionEventDecoder.ClusterSessionId(); correlationId = sessionEventDecoder.CorrelationId(); + leaderMemberId = sessionEventDecoder.LeaderMemberId(); eventCode = sessionEventDecoder.Code(); detail = sessionEventDecoder.Detail(); break; @@ -170,7 +182,7 @@ public ControlledFragmentHandlerAction OnFragment(IDirectBuffer buffer, int offs break; default: - throw new InvalidOperationException("unknown templateId: " + templateId); + throw new ClusterException("unknown templateId: " + templateId); } pollComplete = true; diff --git a/src/Adaptive.Cluster/Client/IEgressListener.cs b/src/Adaptive.Cluster/Client/IEgressListener.cs new file mode 100644 index 00000000..a85fa79b --- /dev/null +++ b/src/Adaptive.Cluster/Client/IEgressListener.cs @@ -0,0 +1,14 @@ +using Adaptive.Cluster.Codecs; + +namespace Adaptive.Cluster.Client +{ + /// + /// Interface for consuming messages coming from the cluster that also include administrative events. + /// + public interface IEgressListener : ISessionMessageListener + { + void SessionEvent(long correlationId, long clusterSessionId, int leaderMemberId, EventCode code, string detail); + + void NewLeader(long clusterSessionId, int leaderMemberId, string memberEndpoints); + } +} \ No newline at end of file diff --git a/src/Adaptive.Cluster/Client/ISessionMessageListener.cs b/src/Adaptive.Cluster/Client/ISessionMessageListener.cs new file mode 100644 index 00000000..301d5212 --- /dev/null +++ b/src/Adaptive.Cluster/Client/ISessionMessageListener.cs @@ -0,0 +1,30 @@ +using Adaptive.Aeron.LogBuffer; +using Adaptive.Agrona; + +namespace Adaptive.Cluster.Client +{ + /// + /// Interface for consuming messages on a given session from the cluster. + /// + public interface ISessionMessageListener + { + /// + /// Message event returned from the cluster. + /// + /// to associate with the ingress message to which it is correlated. + /// to which the message belongs. + /// at which the correlated ingress was sequenced in the cluster. + /// containing the message. + /// at which the message begins. + /// of the message in bytes. + /// Aeron header associated with the message fragment. + void OnMessage( + long correlationId, + long clusterSessionId, + long timestamp, + IDirectBuffer buffer, + int offset, + int length, + Header header); + } +} \ No newline at end of file diff --git a/src/Adaptive.Cluster/Client/SessionDecorator.cs b/src/Adaptive.Cluster/Client/SessionDecorator.cs index 041239a4..2433ad9a 100644 --- a/src/Adaptive.Cluster/Client/SessionDecorator.cs +++ b/src/Adaptive.Cluster/Client/SessionDecorator.cs @@ -21,6 +21,7 @@ public class SessionDecorator /// public static readonly int SESSION_HEADER_LENGTH = MessageHeaderEncoder.ENCODED_LENGTH + SessionHeaderEncoder.BLOCK_LENGTH; + private long lastCorrelationId; private readonly DirectBufferVector[] vectors = new DirectBufferVector[2]; private readonly DirectBufferVector messageBuffer = new DirectBufferVector(); private readonly SessionHeaderEncoder sessionHeaderEncoder = new SessionHeaderEncoder(); @@ -29,13 +30,19 @@ public class SessionDecorator /// Construct a new session header wrapper. /// /// that has been allocated by the cluster. - public SessionDecorator(long clusterSessionId) + /// the last correlation id that was sent to the cluster with this session. + public SessionDecorator(long clusterSessionId, long lastCorrelationId = Aeron.Aeron.NULL_VALUE) { UnsafeBuffer headerBuffer = new UnsafeBuffer(new byte[SESSION_HEADER_LENGTH]); - sessionHeaderEncoder.WrapAndApplyHeader(headerBuffer, 0, new MessageHeaderEncoder()).ClusterSessionId(clusterSessionId); + sessionHeaderEncoder + .WrapAndApplyHeader(headerBuffer, 0, new MessageHeaderEncoder()) + .ClusterSessionId(clusterSessionId) + .Timestamp(Aeron.Aeron.NULL_VALUE); vectors[0] = new DirectBufferVector(headerBuffer, 0, SESSION_HEADER_LENGTH); vectors[1] = messageBuffer; + + this.lastCorrelationId = lastCorrelationId; } /// @@ -47,6 +54,27 @@ public void ClusterSessionId(long clusterSessionId) sessionHeaderEncoder.ClusterSessionId(clusterSessionId); } + /// + /// Get the last correlation id generated for this session. Starts with . + /// + /// the last correlation id generated for this session. + /// + public long LastCorrelationId() + { + return lastCorrelationId; + } + + /// + /// Generate a new correlation id to be used for this session. This is not threadsafe. If you require a threadsafe + /// correlation id generation then use . + /// + /// a new correlation id to be used for this session. + /// + public long NextCorrelationId() + { + return ++lastCorrelationId; + } + /// /// Non-blocking publish of a partial buffer containing a message plus session header to a cluster. /// @@ -63,29 +91,9 @@ public void ClusterSessionId(long clusterSessionId) public long Offer(Publication publication, long correlationId, IDirectBuffer buffer, int offset, int length) { sessionHeaderEncoder.CorrelationId(correlationId); - sessionHeaderEncoder.Timestamp(0L); messageBuffer.Reset(buffer, offset, length); return publication.Offer(vectors, null); } - - /// - /// Non-blocking publish of a partial buffer containing a message plus session header to a cluster. - /// - /// to be offer to. - /// to be used to identify the message to the cluster. - /// for the message. - /// containing message. - /// offset in the buffer at which the encoded message begins. - /// in bytes of the encoded message. - /// the same as . - public long Offer(Publication publication, long correlationId, long timestampMs, IDirectBuffer buffer, int offset, int length) - { - sessionHeaderEncoder.CorrelationId(correlationId); - sessionHeaderEncoder.Timestamp(timestampMs); - messageBuffer.Reset(buffer, offset, length); - - return publication.Offer(vectors); - } } } \ No newline at end of file diff --git a/src/Adaptive.Cluster/Codecs/AppendedPositionDecoder.cs b/src/Adaptive.Cluster/Codecs/AppendedPositionDecoder.cs index 88f86048..acca2762 100644 --- a/src/Adaptive.Cluster/Codecs/AppendedPositionDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/AppendedPositionDecoder.cs @@ -88,27 +88,27 @@ public void Limit(int limit) this._limit = limit; } - public static int LogPositionId() + public static int LeadershipTermIdId() { return 1; } - public static int LogPositionSinceVersion() + public static int LeadershipTermIdSinceVersion() { return 0; } - public static int LogPositionEncodingOffset() + public static int LeadershipTermIdEncodingOffset() { return 0; } - public static int LogPositionEncodingLength() + public static int LeadershipTermIdEncodingLength() { return 8; } - public static string LogPositionMetaAttribute(MetaAttribute metaAttribute) + public static string LeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -121,48 +121,48 @@ public static string LogPositionMetaAttribute(MetaAttribute metaAttribute) return ""; } - public static long LogPositionNullValue() + public static long LeadershipTermIdNullValue() { return -9223372036854775808L; } - public static long LogPositionMinValue() + public static long LeadershipTermIdMinValue() { return -9223372036854775807L; } - public static long LogPositionMaxValue() + public static long LeadershipTermIdMaxValue() { return 9223372036854775807L; } - public long LogPosition() + public long LeadershipTermId() { return _buffer.GetLong(_offset + 0, ByteOrder.LittleEndian); } - public static int LeadershipTermIdId() + public static int LogPositionId() { return 2; } - public static int LeadershipTermIdSinceVersion() + public static int LogPositionSinceVersion() { return 0; } - public static int LeadershipTermIdEncodingOffset() + public static int LogPositionEncodingOffset() { return 8; } - public static int LeadershipTermIdEncodingLength() + public static int LogPositionEncodingLength() { return 8; } - public static string LeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) + public static string LogPositionMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -175,22 +175,22 @@ public static string LeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) return ""; } - public static long LeadershipTermIdNullValue() + public static long LogPositionNullValue() { return -9223372036854775808L; } - public static long LeadershipTermIdMinValue() + public static long LogPositionMinValue() { return -9223372036854775807L; } - public static long LeadershipTermIdMaxValue() + public static long LogPositionMaxValue() { return 9223372036854775807L; } - public long LeadershipTermId() + public long LogPosition() { return _buffer.GetLong(_offset + 8, ByteOrder.LittleEndian); } @@ -279,16 +279,16 @@ public StringBuilder AppendTo(StringBuilder builder) } builder.Append(BLOCK_LENGTH); builder.Append("):"); - //Token{signal=BEGIN_FIELD, name='logPosition', referencedName='null', description='null', id=1, version=0, deprecated=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='leadershipTermId', referencedName='null', description='null', id=1, version=0, deprecated=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=0, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("LogPosition="); - builder.Append(LogPosition()); - builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='leadershipTermId', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("LeadershipTermId="); builder.Append(LeadershipTermId()); builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='logPosition', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LogPosition="); + builder.Append(LogPosition()); + builder.Append('|'); //Token{signal=BEGIN_FIELD, name='followerMemberId', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("FollowerMemberId="); diff --git a/src/Adaptive.Cluster/Codecs/AppendedPositionEncoder.cs b/src/Adaptive.Cluster/Codecs/AppendedPositionEncoder.cs index 9254c853..ae55302b 100644 --- a/src/Adaptive.Cluster/Codecs/AppendedPositionEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/AppendedPositionEncoder.cs @@ -96,64 +96,64 @@ public void Limit(int limit) this._limit = limit; } - public static int LogPositionEncodingOffset() + public static int LeadershipTermIdEncodingOffset() { return 0; } - public static int LogPositionEncodingLength() + public static int LeadershipTermIdEncodingLength() { return 8; } - public static long LogPositionNullValue() + public static long LeadershipTermIdNullValue() { return -9223372036854775808L; } - public static long LogPositionMinValue() + public static long LeadershipTermIdMinValue() { return -9223372036854775807L; } - public static long LogPositionMaxValue() + public static long LeadershipTermIdMaxValue() { return 9223372036854775807L; } - public AppendedPositionEncoder LogPosition(long value) + public AppendedPositionEncoder LeadershipTermId(long value) { _buffer.PutLong(_offset + 0, value, ByteOrder.LittleEndian); return this; } - public static int LeadershipTermIdEncodingOffset() + public static int LogPositionEncodingOffset() { return 8; } - public static int LeadershipTermIdEncodingLength() + public static int LogPositionEncodingLength() { return 8; } - public static long LeadershipTermIdNullValue() + public static long LogPositionNullValue() { return -9223372036854775808L; } - public static long LeadershipTermIdMinValue() + public static long LogPositionMinValue() { return -9223372036854775807L; } - public static long LeadershipTermIdMaxValue() + public static long LogPositionMaxValue() { return 9223372036854775807L; } - public AppendedPositionEncoder LeadershipTermId(long value) + public AppendedPositionEncoder LogPosition(long value) { _buffer.PutLong(_offset + 8, value, ByteOrder.LittleEndian); return this; diff --git a/src/Adaptive.Cluster/Codecs/CancelTimerDecoder.cs b/src/Adaptive.Cluster/Codecs/CancelTimerDecoder.cs index 3886adde..56a65b5b 100644 --- a/src/Adaptive.Cluster/Codecs/CancelTimerDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/CancelTimerDecoder.cs @@ -10,7 +10,7 @@ namespace Adaptive.Cluster.Codecs { public class CancelTimerDecoder { public const ushort BLOCK_LENGTH = 8; - public const ushort TEMPLATE_ID = 31; + public const ushort TEMPLATE_ID = 32; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; diff --git a/src/Adaptive.Cluster/Codecs/CancelTimerEncoder.cs b/src/Adaptive.Cluster/Codecs/CancelTimerEncoder.cs index 3d0ec5f7..eef4ba59 100644 --- a/src/Adaptive.Cluster/Codecs/CancelTimerEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/CancelTimerEncoder.cs @@ -10,7 +10,7 @@ namespace Adaptive.Cluster.Codecs { public class CancelTimerEncoder { public const ushort BLOCK_LENGTH = 8; - public const ushort TEMPLATE_ID = 31; + public const ushort TEMPLATE_ID = 32; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; diff --git a/src/Adaptive.Cluster/Codecs/CanvassPositionDecoder.cs b/src/Adaptive.Cluster/Codecs/CanvassPositionDecoder.cs index 07dec85b..d551669a 100644 --- a/src/Adaptive.Cluster/Codecs/CanvassPositionDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/CanvassPositionDecoder.cs @@ -88,27 +88,27 @@ public void Limit(int limit) this._limit = limit; } - public static int LogPositionId() + public static int LogLeadershipTermIdId() { return 1; } - public static int LogPositionSinceVersion() + public static int LogLeadershipTermIdSinceVersion() { return 0; } - public static int LogPositionEncodingOffset() + public static int LogLeadershipTermIdEncodingOffset() { return 0; } - public static int LogPositionEncodingLength() + public static int LogLeadershipTermIdEncodingLength() { return 8; } - public static string LogPositionMetaAttribute(MetaAttribute metaAttribute) + public static string LogLeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -121,48 +121,48 @@ public static string LogPositionMetaAttribute(MetaAttribute metaAttribute) return ""; } - public static long LogPositionNullValue() + public static long LogLeadershipTermIdNullValue() { return -9223372036854775808L; } - public static long LogPositionMinValue() + public static long LogLeadershipTermIdMinValue() { return -9223372036854775807L; } - public static long LogPositionMaxValue() + public static long LogLeadershipTermIdMaxValue() { return 9223372036854775807L; } - public long LogPosition() + public long LogLeadershipTermId() { return _buffer.GetLong(_offset + 0, ByteOrder.LittleEndian); } - public static int LeadershipTermIdId() + public static int LogPositionId() { return 2; } - public static int LeadershipTermIdSinceVersion() + public static int LogPositionSinceVersion() { return 0; } - public static int LeadershipTermIdEncodingOffset() + public static int LogPositionEncodingOffset() { return 8; } - public static int LeadershipTermIdEncodingLength() + public static int LogPositionEncodingLength() { return 8; } - public static string LeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) + public static string LogPositionMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -175,22 +175,22 @@ public static string LeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) return ""; } - public static long LeadershipTermIdNullValue() + public static long LogPositionNullValue() { return -9223372036854775808L; } - public static long LeadershipTermIdMinValue() + public static long LogPositionMinValue() { return -9223372036854775807L; } - public static long LeadershipTermIdMaxValue() + public static long LogPositionMaxValue() { return 9223372036854775807L; } - public long LeadershipTermId() + public long LogPosition() { return _buffer.GetLong(_offset + 8, ByteOrder.LittleEndian); } @@ -279,15 +279,15 @@ public StringBuilder AppendTo(StringBuilder builder) } builder.Append(BLOCK_LENGTH); builder.Append("):"); - //Token{signal=BEGIN_FIELD, name='logPosition', referencedName='null', description='null', id=1, version=0, deprecated=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='logLeadershipTermId', referencedName='null', description='null', id=1, version=0, deprecated=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=0, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("LogPosition="); - builder.Append(LogPosition()); + builder.Append("LogLeadershipTermId="); + builder.Append(LogLeadershipTermId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='leadershipTermId', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='logPosition', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("LeadershipTermId="); - builder.Append(LeadershipTermId()); + builder.Append("LogPosition="); + builder.Append(LogPosition()); builder.Append('|'); //Token{signal=BEGIN_FIELD, name='followerMemberId', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} diff --git a/src/Adaptive.Cluster/Codecs/CanvassPositionEncoder.cs b/src/Adaptive.Cluster/Codecs/CanvassPositionEncoder.cs index ad6651e0..3735d62b 100644 --- a/src/Adaptive.Cluster/Codecs/CanvassPositionEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/CanvassPositionEncoder.cs @@ -96,64 +96,64 @@ public void Limit(int limit) this._limit = limit; } - public static int LogPositionEncodingOffset() + public static int LogLeadershipTermIdEncodingOffset() { return 0; } - public static int LogPositionEncodingLength() + public static int LogLeadershipTermIdEncodingLength() { return 8; } - public static long LogPositionNullValue() + public static long LogLeadershipTermIdNullValue() { return -9223372036854775808L; } - public static long LogPositionMinValue() + public static long LogLeadershipTermIdMinValue() { return -9223372036854775807L; } - public static long LogPositionMaxValue() + public static long LogLeadershipTermIdMaxValue() { return 9223372036854775807L; } - public CanvassPositionEncoder LogPosition(long value) + public CanvassPositionEncoder LogLeadershipTermId(long value) { _buffer.PutLong(_offset + 0, value, ByteOrder.LittleEndian); return this; } - public static int LeadershipTermIdEncodingOffset() + public static int LogPositionEncodingOffset() { return 8; } - public static int LeadershipTermIdEncodingLength() + public static int LogPositionEncodingLength() { return 8; } - public static long LeadershipTermIdNullValue() + public static long LogPositionNullValue() { return -9223372036854775808L; } - public static long LeadershipTermIdMinValue() + public static long LogPositionMinValue() { return -9223372036854775807L; } - public static long LeadershipTermIdMaxValue() + public static long LogPositionMaxValue() { return 9223372036854775807L; } - public CanvassPositionEncoder LeadershipTermId(long value) + public CanvassPositionEncoder LogPosition(long value) { _buffer.PutLong(_offset + 8, value, ByteOrder.LittleEndian); return this; diff --git a/src/Adaptive.Cluster/Codecs/CatchupPositionDecoder.cs b/src/Adaptive.Cluster/Codecs/CatchupPositionDecoder.cs new file mode 100644 index 00000000..aa654f28 --- /dev/null +++ b/src/Adaptive.Cluster/Codecs/CatchupPositionDecoder.cs @@ -0,0 +1,302 @@ +/* Generated SBE (Simple Binary Encoding) message codec */ +using System; +using System.Text; +using System.Collections.Generic; +using Adaptive.Agrona; + + +namespace Adaptive.Cluster.Codecs { + +public class CatchupPositionDecoder +{ + public const ushort BLOCK_LENGTH = 20; + public const ushort TEMPLATE_ID = 56; + public const ushort SCHEMA_ID = 1; + public const ushort SCHEMA_VERSION = 1; + + private CatchupPositionDecoder _parentMessage; + private IDirectBuffer _buffer; + protected int _offset; + protected int _limit; + protected int _actingBlockLength; + protected int _actingVersion; + + public CatchupPositionDecoder() + { + _parentMessage = this; + } + + public ushort SbeBlockLength() + { + return BLOCK_LENGTH; + } + + public ushort SbeTemplateId() + { + return TEMPLATE_ID; + } + + public ushort SbeSchemaId() + { + return SCHEMA_ID; + } + + public ushort SbeSchemaVersion() + { + return SCHEMA_VERSION; + } + + public string SbeSemanticType() + { + return ""; + } + + public IDirectBuffer Buffer() + { + return _buffer; + } + + public int Offset() + { + return _offset; + } + + public CatchupPositionDecoder Wrap( + IDirectBuffer buffer, int offset, int actingBlockLength, int actingVersion) + { + this._buffer = buffer; + this._offset = offset; + this._actingBlockLength = actingBlockLength; + this._actingVersion = actingVersion; + Limit(offset + actingBlockLength); + + return this; + } + + public int EncodedLength() + { + return _limit - _offset; + } + + public int Limit() + { + return _limit; + } + + public void Limit(int limit) + { + this._limit = limit; + } + + public static int LeadershipTermIdId() + { + return 1; + } + + public static int LeadershipTermIdSinceVersion() + { + return 0; + } + + public static int LeadershipTermIdEncodingOffset() + { + return 0; + } + + public static int LeadershipTermIdEncodingLength() + { + return 8; + } + + public static string LeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long LeadershipTermIdNullValue() + { + return -9223372036854775808L; + } + + public static long LeadershipTermIdMinValue() + { + return -9223372036854775807L; + } + + public static long LeadershipTermIdMaxValue() + { + return 9223372036854775807L; + } + + public long LeadershipTermId() + { + return _buffer.GetLong(_offset + 0, ByteOrder.LittleEndian); + } + + + public static int LogPositionId() + { + return 2; + } + + public static int LogPositionSinceVersion() + { + return 0; + } + + public static int LogPositionEncodingOffset() + { + return 8; + } + + public static int LogPositionEncodingLength() + { + return 8; + } + + public static string LogPositionMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long LogPositionNullValue() + { + return -9223372036854775808L; + } + + public static long LogPositionMinValue() + { + return -9223372036854775807L; + } + + public static long LogPositionMaxValue() + { + return 9223372036854775807L; + } + + public long LogPosition() + { + return _buffer.GetLong(_offset + 8, ByteOrder.LittleEndian); + } + + + public static int FollowerMemberIdId() + { + return 3; + } + + public static int FollowerMemberIdSinceVersion() + { + return 0; + } + + public static int FollowerMemberIdEncodingOffset() + { + return 16; + } + + public static int FollowerMemberIdEncodingLength() + { + return 4; + } + + public static string FollowerMemberIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static int FollowerMemberIdNullValue() + { + return -2147483648; + } + + public static int FollowerMemberIdMinValue() + { + return -2147483647; + } + + public static int FollowerMemberIdMaxValue() + { + return 2147483647; + } + + public int FollowerMemberId() + { + return _buffer.GetInt(_offset + 16, ByteOrder.LittleEndian); + } + + + + public override string ToString() + { + return AppendTo(new StringBuilder(100)).ToString(); + } + + public StringBuilder AppendTo(StringBuilder builder) + { + int originalLimit = Limit(); + Limit(_offset + _actingBlockLength); + builder.Append("[CatchupPosition](sbeTemplateId="); + builder.Append(TEMPLATE_ID); + builder.Append("|sbeSchemaId="); + builder.Append(SCHEMA_ID); + builder.Append("|sbeSchemaVersion="); + if (_parentMessage._actingVersion != SCHEMA_VERSION) + { + builder.Append(_parentMessage._actingVersion); + builder.Append('/'); + } + builder.Append(SCHEMA_VERSION); + builder.Append("|sbeBlockLength="); + if (_actingBlockLength != BLOCK_LENGTH) + { + builder.Append(_actingBlockLength); + builder.Append('/'); + } + builder.Append(BLOCK_LENGTH); + builder.Append("):"); + //Token{signal=BEGIN_FIELD, name='leadershipTermId', referencedName='null', description='null', id=1, version=0, deprecated=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=0, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LeadershipTermId="); + builder.Append(LeadershipTermId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='logPosition', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LogPosition="); + builder.Append(LogPosition()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='followerMemberId', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("FollowerMemberId="); + builder.Append(FollowerMemberId()); + + Limit(originalLimit); + + return builder; + } +} +} diff --git a/src/Adaptive.Cluster/Codecs/ClusterActionAckEncoder.cs b/src/Adaptive.Cluster/Codecs/CatchupPositionEncoder.cs similarity index 74% rename from src/Adaptive.Cluster/Codecs/ClusterActionAckEncoder.cs rename to src/Adaptive.Cluster/Codecs/CatchupPositionEncoder.cs index aec9fe8e..66aaebb9 100644 --- a/src/Adaptive.Cluster/Codecs/ClusterActionAckEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/CatchupPositionEncoder.cs @@ -7,19 +7,19 @@ namespace Adaptive.Cluster.Codecs { -public class ClusterActionAckEncoder +public class CatchupPositionEncoder { - public const ushort BLOCK_LENGTH = 24; - public const ushort TEMPLATE_ID = 32; + public const ushort BLOCK_LENGTH = 20; + public const ushort TEMPLATE_ID = 56; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; - private ClusterActionAckEncoder _parentMessage; + private CatchupPositionEncoder _parentMessage; private IMutableDirectBuffer _buffer; protected int _offset; protected int _limit; - public ClusterActionAckEncoder() + public CatchupPositionEncoder() { _parentMessage = this; } @@ -59,7 +59,7 @@ public int Offset() return _offset; } - public ClusterActionAckEncoder Wrap(IMutableDirectBuffer buffer, int offset) + public CatchupPositionEncoder Wrap(IMutableDirectBuffer buffer, int offset) { this._buffer = buffer; this._offset = offset; @@ -68,7 +68,7 @@ public ClusterActionAckEncoder Wrap(IMutableDirectBuffer buffer, int offset) return this; } - public ClusterActionAckEncoder WrapAndApplyHeader( + public CatchupPositionEncoder WrapAndApplyHeader( IMutableDirectBuffer buffer, int offset, MessageHeaderEncoder headerEncoder) { headerEncoder @@ -96,118 +96,102 @@ public void Limit(int limit) this._limit = limit; } - public static int LogPositionEncodingOffset() + public static int LeadershipTermIdEncodingOffset() { return 0; } - public static int LogPositionEncodingLength() + public static int LeadershipTermIdEncodingLength() { return 8; } - public static long LogPositionNullValue() + public static long LeadershipTermIdNullValue() { return -9223372036854775808L; } - public static long LogPositionMinValue() + public static long LeadershipTermIdMinValue() { return -9223372036854775807L; } - public static long LogPositionMaxValue() + public static long LeadershipTermIdMaxValue() { return 9223372036854775807L; } - public ClusterActionAckEncoder LogPosition(long value) + public CatchupPositionEncoder LeadershipTermId(long value) { _buffer.PutLong(_offset + 0, value, ByteOrder.LittleEndian); return this; } - public static int LeadershipTermIdEncodingOffset() + public static int LogPositionEncodingOffset() { return 8; } - public static int LeadershipTermIdEncodingLength() + public static int LogPositionEncodingLength() { return 8; } - public static long LeadershipTermIdNullValue() + public static long LogPositionNullValue() { return -9223372036854775808L; } - public static long LeadershipTermIdMinValue() + public static long LogPositionMinValue() { return -9223372036854775807L; } - public static long LeadershipTermIdMaxValue() + public static long LogPositionMaxValue() { return 9223372036854775807L; } - public ClusterActionAckEncoder LeadershipTermId(long value) + public CatchupPositionEncoder LogPosition(long value) { _buffer.PutLong(_offset + 8, value, ByteOrder.LittleEndian); return this; } - public static int ServiceIdEncodingOffset() + public static int FollowerMemberIdEncodingOffset() { return 16; } - public static int ServiceIdEncodingLength() + public static int FollowerMemberIdEncodingLength() { return 4; } - public static int ServiceIdNullValue() + public static int FollowerMemberIdNullValue() { return -2147483648; } - public static int ServiceIdMinValue() + public static int FollowerMemberIdMinValue() { return -2147483647; } - public static int ServiceIdMaxValue() + public static int FollowerMemberIdMaxValue() { return 2147483647; } - public ClusterActionAckEncoder ServiceId(int value) + public CatchupPositionEncoder FollowerMemberId(int value) { _buffer.PutInt(_offset + 16, value, ByteOrder.LittleEndian); return this; } - public static int ActionEncodingOffset() - { - return 20; - } - - public static int ActionEncodingLength() - { - return 4; - } - - public ClusterActionAckEncoder Action(ClusterAction value) - { - _buffer.PutInt(_offset + 20, (int)value, ByteOrder.LittleEndian); - return this; - } - public override string ToString() { @@ -216,7 +200,7 @@ public override string ToString() public StringBuilder AppendTo(StringBuilder builder) { - ClusterActionAckDecoder writer = new ClusterActionAckDecoder(); + CatchupPositionDecoder writer = new CatchupPositionDecoder(); writer.Wrap(_buffer, _offset, BLOCK_LENGTH, SCHEMA_VERSION); return writer.AppendTo(builder); diff --git a/src/Adaptive.Cluster/Codecs/ClientSessionDecoder.cs b/src/Adaptive.Cluster/Codecs/ClientSessionDecoder.cs index e5d00ad0..f744179a 100644 --- a/src/Adaptive.Cluster/Codecs/ClientSessionDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/ClientSessionDecoder.cs @@ -9,7 +9,7 @@ namespace Adaptive.Cluster.Codecs { public class ClientSessionDecoder { - public const ushort BLOCK_LENGTH = 12; + public const ushort BLOCK_LENGTH = 20; public const ushort TEMPLATE_ID = 102; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; @@ -142,11 +142,65 @@ public long ClusterSessionId() } - public static int ResponseStreamIdId() + public static int LastCorrelationIdId() { return 2; } + public static int LastCorrelationIdSinceVersion() + { + return 0; + } + + public static int LastCorrelationIdEncodingOffset() + { + return 8; + } + + public static int LastCorrelationIdEncodingLength() + { + return 8; + } + + public static string LastCorrelationIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long LastCorrelationIdNullValue() + { + return -9223372036854775808L; + } + + public static long LastCorrelationIdMinValue() + { + return -9223372036854775807L; + } + + public static long LastCorrelationIdMaxValue() + { + return 9223372036854775807L; + } + + public long LastCorrelationId() + { + return _buffer.GetLong(_offset + 8, ByteOrder.LittleEndian); + } + + + public static int ResponseStreamIdId() + { + return 3; + } + public static int ResponseStreamIdSinceVersion() { return 0; @@ -154,7 +208,7 @@ public static int ResponseStreamIdSinceVersion() public static int ResponseStreamIdEncodingOffset() { - return 8; + return 16; } public static int ResponseStreamIdEncodingLength() @@ -192,13 +246,13 @@ public static int ResponseStreamIdMaxValue() public int ResponseStreamId() { - return _buffer.GetInt(_offset + 8, ByteOrder.LittleEndian); + return _buffer.GetInt(_offset + 16, ByteOrder.LittleEndian); } public static int ResponseChannelId() { - return 3; + return 4; } public static int ResponseChannelSinceVersion() @@ -273,7 +327,7 @@ public string ResponseChannel() public static int EncodedPrincipalId() { - return 4; + return 5; } public static int EncodedPrincipalSinceVersion() @@ -363,16 +417,21 @@ public StringBuilder AppendTo(StringBuilder builder) builder.Append("ClusterSessionId="); builder.Append(ClusterSessionId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='responseStreamId', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='lastCorrelationId', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LastCorrelationId="); + builder.Append(LastCorrelationId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='responseStreamId', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("ResponseStreamId="); builder.Append(ResponseStreamId()); builder.Append('|'); - //Token{signal=BEGIN_VAR_DATA, name='responseChannel', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=12, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_VAR_DATA, name='responseChannel', referencedName='null', description='null', id=4, version=0, deprecated=0, encodedLength=0, offset=20, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("ResponseChannel="); builder.Append(ResponseChannel()); builder.Append('|'); - //Token{signal=BEGIN_VAR_DATA, name='encodedPrincipal', referencedName='null', description='null', id=4, version=0, deprecated=0, encodedLength=0, offset=-1, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_VAR_DATA, name='encodedPrincipal', referencedName='null', description='null', id=5, version=0, deprecated=0, encodedLength=0, offset=-1, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("EncodedPrincipal="); builder.Append(EncodedPrincipalLength() + " raw bytes"); diff --git a/src/Adaptive.Cluster/Codecs/ClientSessionEncoder.cs b/src/Adaptive.Cluster/Codecs/ClientSessionEncoder.cs index 6b364f05..db732b04 100644 --- a/src/Adaptive.Cluster/Codecs/ClientSessionEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/ClientSessionEncoder.cs @@ -9,7 +9,7 @@ namespace Adaptive.Cluster.Codecs { public class ClientSessionEncoder { - public const ushort BLOCK_LENGTH = 12; + public const ushort BLOCK_LENGTH = 20; public const ushort TEMPLATE_ID = 102; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; @@ -128,11 +128,43 @@ public ClientSessionEncoder ClusterSessionId(long value) } - public static int ResponseStreamIdEncodingOffset() + public static int LastCorrelationIdEncodingOffset() { return 8; } + public static int LastCorrelationIdEncodingLength() + { + return 8; + } + + public static long LastCorrelationIdNullValue() + { + return -9223372036854775808L; + } + + public static long LastCorrelationIdMinValue() + { + return -9223372036854775807L; + } + + public static long LastCorrelationIdMaxValue() + { + return 9223372036854775807L; + } + + public ClientSessionEncoder LastCorrelationId(long value) + { + _buffer.PutLong(_offset + 8, value, ByteOrder.LittleEndian); + return this; + } + + + public static int ResponseStreamIdEncodingOffset() + { + return 16; + } + public static int ResponseStreamIdEncodingLength() { return 4; @@ -155,14 +187,14 @@ public static int ResponseStreamIdMaxValue() public ClientSessionEncoder ResponseStreamId(int value) { - _buffer.PutInt(_offset + 8, value, ByteOrder.LittleEndian); + _buffer.PutInt(_offset + 16, value, ByteOrder.LittleEndian); return this; } public static int ResponseChannelId() { - return 3; + return 4; } public static string ResponseChannelCharacterEncoding() @@ -239,7 +271,7 @@ public ClientSessionEncoder ResponseChannel(string value) public static int EncodedPrincipalId() { - return 4; + return 5; } public static string EncodedPrincipalMetaAttribute(MetaAttribute metaAttribute) diff --git a/src/Adaptive.Cluster/Codecs/CloseSessionDecoder.cs b/src/Adaptive.Cluster/Codecs/CloseSessionDecoder.cs index 0232f9b5..d64fc039 100644 --- a/src/Adaptive.Cluster/Codecs/CloseSessionDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/CloseSessionDecoder.cs @@ -10,7 +10,7 @@ namespace Adaptive.Cluster.Codecs { public class CloseSessionDecoder { public const ushort BLOCK_LENGTH = 8; - public const ushort TEMPLATE_ID = 34; + public const ushort TEMPLATE_ID = 30; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; diff --git a/src/Adaptive.Cluster/Codecs/CloseSessionEncoder.cs b/src/Adaptive.Cluster/Codecs/CloseSessionEncoder.cs index 68bcba3b..619dccd2 100644 --- a/src/Adaptive.Cluster/Codecs/CloseSessionEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/CloseSessionEncoder.cs @@ -10,7 +10,7 @@ namespace Adaptive.Cluster.Codecs { public class CloseSessionEncoder { public const ushort BLOCK_LENGTH = 8; - public const ushort TEMPLATE_ID = 34; + public const ushort TEMPLATE_ID = 30; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; diff --git a/src/Adaptive.Cluster/Codecs/ClusterAction.cs b/src/Adaptive.Cluster/Codecs/ClusterAction.cs index bf3c5972..2ae7592e 100644 --- a/src/Adaptive.Cluster/Codecs/ClusterAction.cs +++ b/src/Adaptive.Cluster/Codecs/ClusterAction.cs @@ -3,14 +3,11 @@ namespace Adaptive.Cluster.Codecs { public enum ClusterAction : int { - INIT = 0, - SNAPSHOT = 1, - READY = 2, - REPLAY = 3, - SUSPEND = 4, - RESUME = 5, - SHUTDOWN = 6, - ABORT = 7, + SUSPEND = 0, + RESUME = 1, + SNAPSHOT = 2, + SHUTDOWN = 3, + ABORT = 4, NULL_VALUE = -2147483648 } } diff --git a/src/Adaptive.Cluster/Codecs/ClusterActionRequestDecoder.cs b/src/Adaptive.Cluster/Codecs/ClusterActionRequestDecoder.cs index f5f0cbc4..cec53d20 100644 --- a/src/Adaptive.Cluster/Codecs/ClusterActionRequestDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/ClusterActionRequestDecoder.cs @@ -333,8 +333,8 @@ public StringBuilder AppendTo(StringBuilder builder) builder.Append("Timestamp="); builder.Append(Timestamp()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='action', referencedName='null', description='null', id=4, version=0, deprecated=0, encodedLength=0, offset=24, componentTokenCount=12, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=BEGIN_ENUM, name='ClusterAction', referencedName='null', description='Action to be taken by a cluster nodes', id=-1, version=0, deprecated=0, encodedLength=4, offset=24, componentTokenCount=10, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='null', timeUnit=null, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='action', referencedName='null', description='null', id=4, version=0, deprecated=0, encodedLength=0, offset=24, componentTokenCount=9, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_ENUM, name='ClusterAction', referencedName='null', description='Action to be taken by a cluster nodes', id=-1, version=0, deprecated=0, encodedLength=4, offset=24, componentTokenCount=7, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='null', timeUnit=null, semanticType='null'}} builder.Append("Action="); builder.Append(Action()); diff --git a/src/Adaptive.Cluster/Codecs/ClusterSessionDecoder.cs b/src/Adaptive.Cluster/Codecs/ClusterSessionDecoder.cs index 337d5996..669e1728 100644 --- a/src/Adaptive.Cluster/Codecs/ClusterSessionDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/ClusterSessionDecoder.cs @@ -142,27 +142,27 @@ public long ClusterSessionId() } - public static int OpenedTermPositionId() + public static int OpenedLogPositionId() { return 2; } - public static int OpenedTermPositionSinceVersion() + public static int OpenedLogPositionSinceVersion() { return 0; } - public static int OpenedTermPositionEncodingOffset() + public static int OpenedLogPositionEncodingOffset() { return 8; } - public static int OpenedTermPositionEncodingLength() + public static int OpenedLogPositionEncodingLength() { return 8; } - public static string OpenedTermPositionMetaAttribute(MetaAttribute metaAttribute) + public static string OpenedLogPositionMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -175,22 +175,22 @@ public static string OpenedTermPositionMetaAttribute(MetaAttribute metaAttribute return ""; } - public static long OpenedTermPositionNullValue() + public static long OpenedLogPositionNullValue() { return -9223372036854775808L; } - public static long OpenedTermPositionMinValue() + public static long OpenedLogPositionMinValue() { return -9223372036854775807L; } - public static long OpenedTermPositionMaxValue() + public static long OpenedLogPositionMaxValue() { return 9223372036854775807L; } - public long OpenedTermPosition() + public long OpenedLogPosition() { return _buffer.GetLong(_offset + 8, ByteOrder.LittleEndian); } @@ -506,10 +506,10 @@ public StringBuilder AppendTo(StringBuilder builder) builder.Append("ClusterSessionId="); builder.Append(ClusterSessionId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='openedTermPosition', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='openedLogPosition', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("OpenedTermPosition="); - builder.Append(OpenedTermPosition()); + builder.Append("OpenedLogPosition="); + builder.Append(OpenedLogPosition()); builder.Append('|'); //Token{signal=BEGIN_FIELD, name='lastCorrelationId', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} diff --git a/src/Adaptive.Cluster/Codecs/ClusterSessionEncoder.cs b/src/Adaptive.Cluster/Codecs/ClusterSessionEncoder.cs index e501d6c7..d8db0ed6 100644 --- a/src/Adaptive.Cluster/Codecs/ClusterSessionEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/ClusterSessionEncoder.cs @@ -128,32 +128,32 @@ public ClusterSessionEncoder ClusterSessionId(long value) } - public static int OpenedTermPositionEncodingOffset() + public static int OpenedLogPositionEncodingOffset() { return 8; } - public static int OpenedTermPositionEncodingLength() + public static int OpenedLogPositionEncodingLength() { return 8; } - public static long OpenedTermPositionNullValue() + public static long OpenedLogPositionNullValue() { return -9223372036854775808L; } - public static long OpenedTermPositionMinValue() + public static long OpenedLogPositionMinValue() { return -9223372036854775807L; } - public static long OpenedTermPositionMaxValue() + public static long OpenedLogPositionMaxValue() { return 9223372036854775807L; } - public ClusterSessionEncoder OpenedTermPosition(long value) + public ClusterSessionEncoder OpenedLogPosition(long value) { _buffer.PutLong(_offset + 8, value, ByteOrder.LittleEndian); return this; diff --git a/src/Adaptive.Cluster/Codecs/CommitPositionDecoder.cs b/src/Adaptive.Cluster/Codecs/CommitPositionDecoder.cs index 0df91272..68f4145e 100644 --- a/src/Adaptive.Cluster/Codecs/CommitPositionDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/CommitPositionDecoder.cs @@ -88,27 +88,27 @@ public void Limit(int limit) this._limit = limit; } - public static int LogPositionId() + public static int LeadershipTermIdId() { return 1; } - public static int LogPositionSinceVersion() + public static int LeadershipTermIdSinceVersion() { return 0; } - public static int LogPositionEncodingOffset() + public static int LeadershipTermIdEncodingOffset() { return 0; } - public static int LogPositionEncodingLength() + public static int LeadershipTermIdEncodingLength() { return 8; } - public static string LogPositionMetaAttribute(MetaAttribute metaAttribute) + public static string LeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -121,48 +121,48 @@ public static string LogPositionMetaAttribute(MetaAttribute metaAttribute) return ""; } - public static long LogPositionNullValue() + public static long LeadershipTermIdNullValue() { return -9223372036854775808L; } - public static long LogPositionMinValue() + public static long LeadershipTermIdMinValue() { return -9223372036854775807L; } - public static long LogPositionMaxValue() + public static long LeadershipTermIdMaxValue() { return 9223372036854775807L; } - public long LogPosition() + public long LeadershipTermId() { return _buffer.GetLong(_offset + 0, ByteOrder.LittleEndian); } - public static int LeadershipTermIdId() + public static int LogPositionId() { return 2; } - public static int LeadershipTermIdSinceVersion() + public static int LogPositionSinceVersion() { return 0; } - public static int LeadershipTermIdEncodingOffset() + public static int LogPositionEncodingOffset() { return 8; } - public static int LeadershipTermIdEncodingLength() + public static int LogPositionEncodingLength() { return 8; } - public static string LeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) + public static string LogPositionMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -175,22 +175,22 @@ public static string LeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) return ""; } - public static long LeadershipTermIdNullValue() + public static long LogPositionNullValue() { return -9223372036854775808L; } - public static long LeadershipTermIdMinValue() + public static long LogPositionMinValue() { return -9223372036854775807L; } - public static long LeadershipTermIdMaxValue() + public static long LogPositionMaxValue() { return 9223372036854775807L; } - public long LeadershipTermId() + public long LogPosition() { return _buffer.GetLong(_offset + 8, ByteOrder.LittleEndian); } @@ -279,16 +279,16 @@ public StringBuilder AppendTo(StringBuilder builder) } builder.Append(BLOCK_LENGTH); builder.Append("):"); - //Token{signal=BEGIN_FIELD, name='logPosition', referencedName='null', description='null', id=1, version=0, deprecated=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='leadershipTermId', referencedName='null', description='null', id=1, version=0, deprecated=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=0, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("LogPosition="); - builder.Append(LogPosition()); - builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='leadershipTermId', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("LeadershipTermId="); builder.Append(LeadershipTermId()); builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='logPosition', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LogPosition="); + builder.Append(LogPosition()); + builder.Append('|'); //Token{signal=BEGIN_FIELD, name='leaderMemberId', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("LeaderMemberId="); diff --git a/src/Adaptive.Cluster/Codecs/CommitPositionEncoder.cs b/src/Adaptive.Cluster/Codecs/CommitPositionEncoder.cs index c2d5531d..c30cffa8 100644 --- a/src/Adaptive.Cluster/Codecs/CommitPositionEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/CommitPositionEncoder.cs @@ -96,64 +96,64 @@ public void Limit(int limit) this._limit = limit; } - public static int LogPositionEncodingOffset() + public static int LeadershipTermIdEncodingOffset() { return 0; } - public static int LogPositionEncodingLength() + public static int LeadershipTermIdEncodingLength() { return 8; } - public static long LogPositionNullValue() + public static long LeadershipTermIdNullValue() { return -9223372036854775808L; } - public static long LogPositionMinValue() + public static long LeadershipTermIdMinValue() { return -9223372036854775807L; } - public static long LogPositionMaxValue() + public static long LeadershipTermIdMaxValue() { return 9223372036854775807L; } - public CommitPositionEncoder LogPosition(long value) + public CommitPositionEncoder LeadershipTermId(long value) { _buffer.PutLong(_offset + 0, value, ByteOrder.LittleEndian); return this; } - public static int LeadershipTermIdEncodingOffset() + public static int LogPositionEncodingOffset() { return 8; } - public static int LeadershipTermIdEncodingLength() + public static int LogPositionEncodingLength() { return 8; } - public static long LeadershipTermIdNullValue() + public static long LogPositionNullValue() { return -9223372036854775808L; } - public static long LeadershipTermIdMinValue() + public static long LogPositionMinValue() { return -9223372036854775807L; } - public static long LeadershipTermIdMaxValue() + public static long LogPositionMaxValue() { return 9223372036854775807L; } - public CommitPositionEncoder LeadershipTermId(long value) + public CommitPositionEncoder LogPosition(long value) { _buffer.PutLong(_offset + 8, value, ByteOrder.LittleEndian); return this; diff --git a/src/Adaptive.Cluster/Codecs/SequencerDecoder.cs b/src/Adaptive.Cluster/Codecs/ConsensusModuleDecoder.cs similarity index 95% rename from src/Adaptive.Cluster/Codecs/SequencerDecoder.cs rename to src/Adaptive.Cluster/Codecs/ConsensusModuleDecoder.cs index c6cef790..e3a5a53f 100644 --- a/src/Adaptive.Cluster/Codecs/SequencerDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/ConsensusModuleDecoder.cs @@ -7,21 +7,21 @@ namespace Adaptive.Cluster.Codecs { -public class SequencerDecoder +public class ConsensusModuleDecoder { public const ushort BLOCK_LENGTH = 8; public const ushort TEMPLATE_ID = 105; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; - private SequencerDecoder _parentMessage; + private ConsensusModuleDecoder _parentMessage; private IDirectBuffer _buffer; protected int _offset; protected int _limit; protected int _actingBlockLength; protected int _actingVersion; - public SequencerDecoder() + public ConsensusModuleDecoder() { _parentMessage = this; } @@ -61,7 +61,7 @@ public int Offset() return _offset; } - public SequencerDecoder Wrap( + public ConsensusModuleDecoder Wrap( IDirectBuffer buffer, int offset, int actingBlockLength, int actingVersion) { this._buffer = buffer; @@ -152,7 +152,7 @@ public StringBuilder AppendTo(StringBuilder builder) { int originalLimit = Limit(); Limit(_offset + _actingBlockLength); - builder.Append("[Sequencer](sbeTemplateId="); + builder.Append("[ConsensusModule](sbeTemplateId="); builder.Append(TEMPLATE_ID); builder.Append("|sbeSchemaId="); builder.Append(SCHEMA_ID); diff --git a/src/Adaptive.Cluster/Codecs/SequencerEncoder.cs b/src/Adaptive.Cluster/Codecs/ConsensusModuleEncoder.cs similarity index 87% rename from src/Adaptive.Cluster/Codecs/SequencerEncoder.cs rename to src/Adaptive.Cluster/Codecs/ConsensusModuleEncoder.cs index 3589cd22..834b4207 100644 --- a/src/Adaptive.Cluster/Codecs/SequencerEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/ConsensusModuleEncoder.cs @@ -7,19 +7,19 @@ namespace Adaptive.Cluster.Codecs { -public class SequencerEncoder +public class ConsensusModuleEncoder { public const ushort BLOCK_LENGTH = 8; public const ushort TEMPLATE_ID = 105; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; - private SequencerEncoder _parentMessage; + private ConsensusModuleEncoder _parentMessage; private IMutableDirectBuffer _buffer; protected int _offset; protected int _limit; - public SequencerEncoder() + public ConsensusModuleEncoder() { _parentMessage = this; } @@ -59,7 +59,7 @@ public int Offset() return _offset; } - public SequencerEncoder Wrap(IMutableDirectBuffer buffer, int offset) + public ConsensusModuleEncoder Wrap(IMutableDirectBuffer buffer, int offset) { this._buffer = buffer; this._offset = offset; @@ -68,7 +68,7 @@ public SequencerEncoder Wrap(IMutableDirectBuffer buffer, int offset) return this; } - public SequencerEncoder WrapAndApplyHeader( + public ConsensusModuleEncoder WrapAndApplyHeader( IMutableDirectBuffer buffer, int offset, MessageHeaderEncoder headerEncoder) { headerEncoder @@ -121,7 +121,7 @@ public static long NextSessionIdMaxValue() return 9223372036854775807L; } - public SequencerEncoder NextSessionId(long value) + public ConsensusModuleEncoder NextSessionId(long value) { _buffer.PutLong(_offset + 0, value, ByteOrder.LittleEndian); return this; @@ -136,7 +136,7 @@ public override string ToString() public StringBuilder AppendTo(StringBuilder builder) { - SequencerDecoder writer = new SequencerDecoder(); + ConsensusModuleDecoder writer = new ConsensusModuleDecoder(); writer.Wrap(_buffer, _offset, BLOCK_LENGTH, SCHEMA_VERSION); return writer.AppendTo(builder); diff --git a/src/Adaptive.Cluster/Codecs/JoinLogDecoder.cs b/src/Adaptive.Cluster/Codecs/JoinLogDecoder.cs index 2968ce90..1d3d5ab7 100644 --- a/src/Adaptive.Cluster/Codecs/JoinLogDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/JoinLogDecoder.cs @@ -9,8 +9,8 @@ namespace Adaptive.Cluster.Codecs { public class JoinLogDecoder { - public const ushort BLOCK_LENGTH = 24; - public const ushort TEMPLATE_ID = 33; + public const ushort BLOCK_LENGTH = 20; + public const ushort TEMPLATE_ID = 40; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; @@ -304,45 +304,6 @@ public int LogStreamId() } - public static int AckBeforeImageId() - { - return 5; - } - - public static int AckBeforeImageSinceVersion() - { - return 0; - } - - public static int AckBeforeImageEncodingOffset() - { - return 20; - } - - public static int AckBeforeImageEncodingLength() - { - return 4; - } - - public static string AckBeforeImageMetaAttribute(MetaAttribute metaAttribute) - { - switch (metaAttribute) - { - case MetaAttribute.EPOCH: return "unix"; - case MetaAttribute.TIME_UNIT: return "nanosecond"; - case MetaAttribute.SEMANTIC_TYPE: return ""; - case MetaAttribute.PRESENCE: return "required"; - } - - return ""; - } - - public BooleanType AckBeforeImage() - { - return (BooleanType)_buffer.GetInt(_offset + 20, ByteOrder.LittleEndian); - } - - public static int LogChannelId() { return 5; @@ -467,12 +428,7 @@ public StringBuilder AppendTo(StringBuilder builder) builder.Append("LogStreamId="); builder.Append(LogStreamId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='ackBeforeImage', referencedName='null', description='null', id=5, version=0, deprecated=0, encodedLength=0, offset=20, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=BEGIN_ENUM, name='BooleanType', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=20, componentTokenCount=4, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='null', timeUnit=null, semanticType='null'}} - builder.Append("AckBeforeImage="); - builder.Append(AckBeforeImage()); - builder.Append('|'); - //Token{signal=BEGIN_VAR_DATA, name='logChannel', referencedName='null', description='null', id=5, version=0, deprecated=0, encodedLength=0, offset=24, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_VAR_DATA, name='logChannel', referencedName='null', description='null', id=5, version=0, deprecated=0, encodedLength=0, offset=20, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("LogChannel="); builder.Append(LogChannel()); diff --git a/src/Adaptive.Cluster/Codecs/JoinLogEncoder.cs b/src/Adaptive.Cluster/Codecs/JoinLogEncoder.cs index 709137e8..b09125c8 100644 --- a/src/Adaptive.Cluster/Codecs/JoinLogEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/JoinLogEncoder.cs @@ -9,8 +9,8 @@ namespace Adaptive.Cluster.Codecs { public class JoinLogEncoder { - public const ushort BLOCK_LENGTH = 24; - public const ushort TEMPLATE_ID = 33; + public const ushort BLOCK_LENGTH = 20; + public const ushort TEMPLATE_ID = 40; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; @@ -224,22 +224,6 @@ public JoinLogEncoder LogStreamId(int value) } - public static int AckBeforeImageEncodingOffset() - { - return 20; - } - - public static int AckBeforeImageEncodingLength() - { - return 4; - } - - public JoinLogEncoder AckBeforeImage(BooleanType value) - { - _buffer.PutInt(_offset + 20, (int)value, ByteOrder.LittleEndian); - return this; - } - public static int LogChannelId() { return 5; diff --git a/src/Adaptive.Cluster/Codecs/Mark/MarkFileHeaderDecoder.cs b/src/Adaptive.Cluster/Codecs/Mark/MarkFileHeaderDecoder.cs index 9fcb013e..588e1a43 100644 --- a/src/Adaptive.Cluster/Codecs/Mark/MarkFileHeaderDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/Mark/MarkFileHeaderDecoder.cs @@ -343,11 +343,65 @@ public long Pid() } - public static int ArchiveStreamIdId() + public static int CandidateTermIdId() { return 6; } + public static int CandidateTermIdSinceVersion() + { + return 0; + } + + public static int CandidateTermIdEncodingOffset() + { + return 32; + } + + public static int CandidateTermIdEncodingLength() + { + return 8; + } + + public static string CandidateTermIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long CandidateTermIdNullValue() + { + return -9223372036854775808L; + } + + public static long CandidateTermIdMinValue() + { + return -9223372036854775807L; + } + + public static long CandidateTermIdMaxValue() + { + return 9223372036854775807L; + } + + public long CandidateTermId() + { + return _buffer.GetLong(_offset + 32, ByteOrder.LittleEndian); + } + + + public static int ArchiveStreamIdId() + { + return 7; + } + public static int ArchiveStreamIdSinceVersion() { return 0; @@ -355,7 +409,7 @@ public static int ArchiveStreamIdSinceVersion() public static int ArchiveStreamIdEncodingOffset() { - return 32; + return 40; } public static int ArchiveStreamIdEncodingLength() @@ -393,31 +447,85 @@ public static int ArchiveStreamIdMaxValue() public int ArchiveStreamId() { - return _buffer.GetInt(_offset + 32, ByteOrder.LittleEndian); + return _buffer.GetInt(_offset + 40, ByteOrder.LittleEndian); } - public static int ServiceControlStreamIdId() + public static int ServiceStreamIdId() { - return 7; + return 8; + } + + public static int ServiceStreamIdSinceVersion() + { + return 0; + } + + public static int ServiceStreamIdEncodingOffset() + { + return 44; + } + + public static int ServiceStreamIdEncodingLength() + { + return 4; + } + + public static string ServiceStreamIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static int ServiceStreamIdNullValue() + { + return -2147483648; + } + + public static int ServiceStreamIdMinValue() + { + return -2147483647; + } + + public static int ServiceStreamIdMaxValue() + { + return 2147483647; + } + + public int ServiceStreamId() + { + return _buffer.GetInt(_offset + 44, ByteOrder.LittleEndian); } - public static int ServiceControlStreamIdSinceVersion() + + public static int ConsensusModuleStreamIdId() + { + return 9; + } + + public static int ConsensusModuleStreamIdSinceVersion() { return 0; } - public static int ServiceControlStreamIdEncodingOffset() + public static int ConsensusModuleStreamIdEncodingOffset() { - return 36; + return 48; } - public static int ServiceControlStreamIdEncodingLength() + public static int ConsensusModuleStreamIdEncodingLength() { return 4; } - public static string ServiceControlStreamIdMetaAttribute(MetaAttribute metaAttribute) + public static string ConsensusModuleStreamIdMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -430,30 +538,30 @@ public static string ServiceControlStreamIdMetaAttribute(MetaAttribute metaAttri return ""; } - public static int ServiceControlStreamIdNullValue() + public static int ConsensusModuleStreamIdNullValue() { return -2147483648; } - public static int ServiceControlStreamIdMinValue() + public static int ConsensusModuleStreamIdMinValue() { return -2147483647; } - public static int ServiceControlStreamIdMaxValue() + public static int ConsensusModuleStreamIdMaxValue() { return 2147483647; } - public int ServiceControlStreamId() + public int ConsensusModuleStreamId() { - return _buffer.GetInt(_offset + 36, ByteOrder.LittleEndian); + return _buffer.GetInt(_offset + 48, ByteOrder.LittleEndian); } public static int IngressStreamIdId() { - return 8; + return 10; } public static int IngressStreamIdSinceVersion() @@ -463,7 +571,7 @@ public static int IngressStreamIdSinceVersion() public static int IngressStreamIdEncodingOffset() { - return 40; + return 52; } public static int IngressStreamIdEncodingLength() @@ -501,13 +609,13 @@ public static int IngressStreamIdMaxValue() public int IngressStreamId() { - return _buffer.GetInt(_offset + 40, ByteOrder.LittleEndian); + return _buffer.GetInt(_offset + 52, ByteOrder.LittleEndian); } public static int MemberIdId() { - return 9; + return 11; } public static int MemberIdSinceVersion() @@ -517,7 +625,7 @@ public static int MemberIdSinceVersion() public static int MemberIdEncodingOffset() { - return 44; + return 56; } public static int MemberIdEncodingLength() @@ -555,13 +663,13 @@ public static int MemberIdMaxValue() public int MemberId() { - return _buffer.GetInt(_offset + 44, ByteOrder.LittleEndian); + return _buffer.GetInt(_offset + 56, ByteOrder.LittleEndian); } public static int ServiceIdId() { - return 10; + return 12; } public static int ServiceIdSinceVersion() @@ -571,7 +679,7 @@ public static int ServiceIdSinceVersion() public static int ServiceIdEncodingOffset() { - return 48; + return 60; } public static int ServiceIdEncodingLength() @@ -609,13 +717,13 @@ public static int ServiceIdMaxValue() public int ServiceId() { - return _buffer.GetInt(_offset + 48, ByteOrder.LittleEndian); + return _buffer.GetInt(_offset + 60, ByteOrder.LittleEndian); } public static int HeaderLengthId() { - return 11; + return 13; } public static int HeaderLengthSinceVersion() @@ -625,7 +733,7 @@ public static int HeaderLengthSinceVersion() public static int HeaderLengthEncodingOffset() { - return 52; + return 64; } public static int HeaderLengthEncodingLength() @@ -663,13 +771,13 @@ public static int HeaderLengthMaxValue() public int HeaderLength() { - return _buffer.GetInt(_offset + 52, ByteOrder.LittleEndian); + return _buffer.GetInt(_offset + 64, ByteOrder.LittleEndian); } public static int ErrorBufferLengthId() { - return 12; + return 14; } public static int ErrorBufferLengthSinceVersion() @@ -679,7 +787,7 @@ public static int ErrorBufferLengthSinceVersion() public static int ErrorBufferLengthEncodingOffset() { - return 56; + return 68; } public static int ErrorBufferLengthEncodingLength() @@ -717,13 +825,13 @@ public static int ErrorBufferLengthMaxValue() public int ErrorBufferLength() { - return _buffer.GetInt(_offset + 56, ByteOrder.LittleEndian); + return _buffer.GetInt(_offset + 68, ByteOrder.LittleEndian); } public static int AeronDirectoryId() { - return 13; + return 15; } public static int AeronDirectorySinceVersion() @@ -798,7 +906,7 @@ public string AeronDirectory() public static int ArchiveChannelId() { - return 14; + return 16; } public static int ArchiveChannelSinceVersion() @@ -873,7 +981,7 @@ public string ArchiveChannel() public static int ServiceControlChannelId() { - return 15; + return 17; } public static int ServiceControlChannelSinceVersion() @@ -948,7 +1056,7 @@ public string ServiceControlChannel() public static int IngressChannelId() { - return 16; + return 18; } public static int IngressChannelSinceVersion() @@ -1023,7 +1131,7 @@ public string IngressChannel() public static int ServiceNameId() { - return 17; + return 19; } public static int ServiceNameSinceVersion() @@ -1098,7 +1206,7 @@ public string ServiceName() public static int AuthenticatorId() { - return 18; + return 20; } public static int AuthenticatorSinceVersion() @@ -1225,62 +1333,72 @@ public StringBuilder AppendTo(StringBuilder builder) builder.Append("Pid="); builder.Append(Pid()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='archiveStreamId', referencedName='null', description='null', id=6, version=0, deprecated=0, encodedLength=0, offset=32, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=32, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='candidateTermId', referencedName='null', description='null', id=6, version=0, deprecated=0, encodedLength=0, offset=32, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=32, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("CandidateTermId="); + builder.Append(CandidateTermId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='archiveStreamId', referencedName='null', description='null', id=7, version=0, deprecated=0, encodedLength=0, offset=40, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=40, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("ArchiveStreamId="); builder.Append(ArchiveStreamId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='serviceControlStreamId', referencedName='null', description='null', id=7, version=0, deprecated=0, encodedLength=0, offset=36, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=36, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("ServiceControlStreamId="); - builder.Append(ServiceControlStreamId()); + //Token{signal=BEGIN_FIELD, name='serviceStreamId', referencedName='null', description='null', id=8, version=0, deprecated=0, encodedLength=0, offset=44, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=44, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("ServiceStreamId="); + builder.Append(ServiceStreamId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='consensusModuleStreamId', referencedName='null', description='null', id=9, version=0, deprecated=0, encodedLength=0, offset=48, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=48, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("ConsensusModuleStreamId="); + builder.Append(ConsensusModuleStreamId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='ingressStreamId', referencedName='null', description='null', id=8, version=0, deprecated=0, encodedLength=0, offset=40, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=40, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='ingressStreamId', referencedName='null', description='null', id=10, version=0, deprecated=0, encodedLength=0, offset=52, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=52, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("IngressStreamId="); builder.Append(IngressStreamId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='memberId', referencedName='null', description='null', id=9, version=0, deprecated=0, encodedLength=0, offset=44, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=44, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='memberId', referencedName='null', description='null', id=11, version=0, deprecated=0, encodedLength=0, offset=56, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=56, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("MemberId="); builder.Append(MemberId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='serviceId', referencedName='null', description='null', id=10, version=0, deprecated=0, encodedLength=0, offset=48, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=48, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='serviceId', referencedName='null', description='null', id=12, version=0, deprecated=0, encodedLength=0, offset=60, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=60, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("ServiceId="); builder.Append(ServiceId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='headerLength', referencedName='null', description='null', id=11, version=0, deprecated=0, encodedLength=0, offset=52, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=52, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='headerLength', referencedName='null', description='null', id=13, version=0, deprecated=0, encodedLength=0, offset=64, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=64, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("HeaderLength="); builder.Append(HeaderLength()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='errorBufferLength', referencedName='null', description='null', id=12, version=0, deprecated=0, encodedLength=0, offset=56, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=56, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='errorBufferLength', referencedName='null', description='null', id=14, version=0, deprecated=0, encodedLength=0, offset=68, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=68, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("ErrorBufferLength="); builder.Append(ErrorBufferLength()); builder.Append('|'); - //Token{signal=BEGIN_VAR_DATA, name='aeronDirectory', referencedName='null', description='null', id=13, version=0, deprecated=0, encodedLength=0, offset=128, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_VAR_DATA, name='aeronDirectory', referencedName='null', description='null', id=15, version=0, deprecated=0, encodedLength=0, offset=128, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("AeronDirectory="); builder.Append(AeronDirectory()); builder.Append('|'); - //Token{signal=BEGIN_VAR_DATA, name='archiveChannel', referencedName='null', description='null', id=14, version=0, deprecated=0, encodedLength=0, offset=-1, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_VAR_DATA, name='archiveChannel', referencedName='null', description='null', id=16, version=0, deprecated=0, encodedLength=0, offset=-1, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("ArchiveChannel="); builder.Append(ArchiveChannel()); builder.Append('|'); - //Token{signal=BEGIN_VAR_DATA, name='serviceControlChannel', referencedName='null', description='null', id=15, version=0, deprecated=0, encodedLength=0, offset=-1, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_VAR_DATA, name='serviceControlChannel', referencedName='null', description='null', id=17, version=0, deprecated=0, encodedLength=0, offset=-1, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("ServiceControlChannel="); builder.Append(ServiceControlChannel()); builder.Append('|'); - //Token{signal=BEGIN_VAR_DATA, name='ingressChannel', referencedName='null', description='null', id=16, version=0, deprecated=0, encodedLength=0, offset=-1, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_VAR_DATA, name='ingressChannel', referencedName='null', description='null', id=18, version=0, deprecated=0, encodedLength=0, offset=-1, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("IngressChannel="); builder.Append(IngressChannel()); builder.Append('|'); - //Token{signal=BEGIN_VAR_DATA, name='serviceName', referencedName='null', description='null', id=17, version=0, deprecated=0, encodedLength=0, offset=-1, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_VAR_DATA, name='serviceName', referencedName='null', description='null', id=19, version=0, deprecated=0, encodedLength=0, offset=-1, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("ServiceName="); builder.Append(ServiceName()); builder.Append('|'); - //Token{signal=BEGIN_VAR_DATA, name='authenticator', referencedName='null', description='null', id=18, version=0, deprecated=0, encodedLength=0, offset=-1, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_VAR_DATA, name='authenticator', referencedName='null', description='null', id=20, version=0, deprecated=0, encodedLength=0, offset=-1, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("Authenticator="); builder.Append(Authenticator()); diff --git a/src/Adaptive.Cluster/Codecs/Mark/MarkFileHeaderEncoder.cs b/src/Adaptive.Cluster/Codecs/Mark/MarkFileHeaderEncoder.cs index 449be8fb..80fb8caa 100644 --- a/src/Adaptive.Cluster/Codecs/Mark/MarkFileHeaderEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/Mark/MarkFileHeaderEncoder.cs @@ -240,11 +240,43 @@ public MarkFileHeaderEncoder Pid(long value) } - public static int ArchiveStreamIdEncodingOffset() + public static int CandidateTermIdEncodingOffset() { return 32; } + public static int CandidateTermIdEncodingLength() + { + return 8; + } + + public static long CandidateTermIdNullValue() + { + return -9223372036854775808L; + } + + public static long CandidateTermIdMinValue() + { + return -9223372036854775807L; + } + + public static long CandidateTermIdMaxValue() + { + return 9223372036854775807L; + } + + public MarkFileHeaderEncoder CandidateTermId(long value) + { + _buffer.PutLong(_offset + 32, value, ByteOrder.LittleEndian); + return this; + } + + + public static int ArchiveStreamIdEncodingOffset() + { + return 40; + } + public static int ArchiveStreamIdEncodingLength() { return 4; @@ -267,46 +299,78 @@ public static int ArchiveStreamIdMaxValue() public MarkFileHeaderEncoder ArchiveStreamId(int value) { - _buffer.PutInt(_offset + 32, value, ByteOrder.LittleEndian); + _buffer.PutInt(_offset + 40, value, ByteOrder.LittleEndian); + return this; + } + + + public static int ServiceStreamIdEncodingOffset() + { + return 44; + } + + public static int ServiceStreamIdEncodingLength() + { + return 4; + } + + public static int ServiceStreamIdNullValue() + { + return -2147483648; + } + + public static int ServiceStreamIdMinValue() + { + return -2147483647; + } + + public static int ServiceStreamIdMaxValue() + { + return 2147483647; + } + + public MarkFileHeaderEncoder ServiceStreamId(int value) + { + _buffer.PutInt(_offset + 44, value, ByteOrder.LittleEndian); return this; } - public static int ServiceControlStreamIdEncodingOffset() + public static int ConsensusModuleStreamIdEncodingOffset() { - return 36; + return 48; } - public static int ServiceControlStreamIdEncodingLength() + public static int ConsensusModuleStreamIdEncodingLength() { return 4; } - public static int ServiceControlStreamIdNullValue() + public static int ConsensusModuleStreamIdNullValue() { return -2147483648; } - public static int ServiceControlStreamIdMinValue() + public static int ConsensusModuleStreamIdMinValue() { return -2147483647; } - public static int ServiceControlStreamIdMaxValue() + public static int ConsensusModuleStreamIdMaxValue() { return 2147483647; } - public MarkFileHeaderEncoder ServiceControlStreamId(int value) + public MarkFileHeaderEncoder ConsensusModuleStreamId(int value) { - _buffer.PutInt(_offset + 36, value, ByteOrder.LittleEndian); + _buffer.PutInt(_offset + 48, value, ByteOrder.LittleEndian); return this; } public static int IngressStreamIdEncodingOffset() { - return 40; + return 52; } public static int IngressStreamIdEncodingLength() @@ -331,14 +395,14 @@ public static int IngressStreamIdMaxValue() public MarkFileHeaderEncoder IngressStreamId(int value) { - _buffer.PutInt(_offset + 40, value, ByteOrder.LittleEndian); + _buffer.PutInt(_offset + 52, value, ByteOrder.LittleEndian); return this; } public static int MemberIdEncodingOffset() { - return 44; + return 56; } public static int MemberIdEncodingLength() @@ -363,14 +427,14 @@ public static int MemberIdMaxValue() public MarkFileHeaderEncoder MemberId(int value) { - _buffer.PutInt(_offset + 44, value, ByteOrder.LittleEndian); + _buffer.PutInt(_offset + 56, value, ByteOrder.LittleEndian); return this; } public static int ServiceIdEncodingOffset() { - return 48; + return 60; } public static int ServiceIdEncodingLength() @@ -395,14 +459,14 @@ public static int ServiceIdMaxValue() public MarkFileHeaderEncoder ServiceId(int value) { - _buffer.PutInt(_offset + 48, value, ByteOrder.LittleEndian); + _buffer.PutInt(_offset + 60, value, ByteOrder.LittleEndian); return this; } public static int HeaderLengthEncodingOffset() { - return 52; + return 64; } public static int HeaderLengthEncodingLength() @@ -427,14 +491,14 @@ public static int HeaderLengthMaxValue() public MarkFileHeaderEncoder HeaderLength(int value) { - _buffer.PutInt(_offset + 52, value, ByteOrder.LittleEndian); + _buffer.PutInt(_offset + 64, value, ByteOrder.LittleEndian); return this; } public static int ErrorBufferLengthEncodingOffset() { - return 56; + return 68; } public static int ErrorBufferLengthEncodingLength() @@ -459,14 +523,14 @@ public static int ErrorBufferLengthMaxValue() public MarkFileHeaderEncoder ErrorBufferLength(int value) { - _buffer.PutInt(_offset + 56, value, ByteOrder.LittleEndian); + _buffer.PutInt(_offset + 68, value, ByteOrder.LittleEndian); return this; } public static int AeronDirectoryId() { - return 13; + return 15; } public static string AeronDirectoryCharacterEncoding() @@ -543,7 +607,7 @@ public MarkFileHeaderEncoder AeronDirectory(string value) public static int ArchiveChannelId() { - return 14; + return 16; } public static string ArchiveChannelCharacterEncoding() @@ -620,7 +684,7 @@ public MarkFileHeaderEncoder ArchiveChannel(string value) public static int ServiceControlChannelId() { - return 15; + return 17; } public static string ServiceControlChannelCharacterEncoding() @@ -697,7 +761,7 @@ public MarkFileHeaderEncoder ServiceControlChannel(string value) public static int IngressChannelId() { - return 16; + return 18; } public static string IngressChannelCharacterEncoding() @@ -774,7 +838,7 @@ public MarkFileHeaderEncoder IngressChannel(string value) public static int ServiceNameId() { - return 17; + return 19; } public static string ServiceNameCharacterEncoding() @@ -851,7 +915,7 @@ public MarkFileHeaderEncoder ServiceName(string value) public static int AuthenticatorId() { - return 18; + return 20; } public static string AuthenticatorCharacterEncoding() diff --git a/src/Adaptive.Cluster/Codecs/NewLeaderEventDecoder.cs b/src/Adaptive.Cluster/Codecs/NewLeaderEventDecoder.cs index c34c3aef..17cc7c11 100644 --- a/src/Adaptive.Cluster/Codecs/NewLeaderEventDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/NewLeaderEventDecoder.cs @@ -9,7 +9,7 @@ namespace Adaptive.Cluster.Codecs { public class NewLeaderEventDecoder { - public const ushort BLOCK_LENGTH = 44; + public const ushort BLOCK_LENGTH = 12; public const ushort TEMPLATE_ID = 6; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; @@ -142,225 +142,9 @@ public long ClusterSessionId() } - public static int LastCorrelationIdId() - { - return 2; - } - - public static int LastCorrelationIdSinceVersion() - { - return 0; - } - - public static int LastCorrelationIdEncodingOffset() - { - return 8; - } - - public static int LastCorrelationIdEncodingLength() - { - return 8; - } - - public static string LastCorrelationIdMetaAttribute(MetaAttribute metaAttribute) - { - switch (metaAttribute) - { - case MetaAttribute.EPOCH: return "unix"; - case MetaAttribute.TIME_UNIT: return "nanosecond"; - case MetaAttribute.SEMANTIC_TYPE: return ""; - case MetaAttribute.PRESENCE: return "required"; - } - - return ""; - } - - public static long LastCorrelationIdNullValue() - { - return -9223372036854775808L; - } - - public static long LastCorrelationIdMinValue() - { - return -9223372036854775807L; - } - - public static long LastCorrelationIdMaxValue() - { - return 9223372036854775807L; - } - - public long LastCorrelationId() - { - return _buffer.GetLong(_offset + 8, ByteOrder.LittleEndian); - } - - - public static int LastMessageTimestampId() - { - return 3; - } - - public static int LastMessageTimestampSinceVersion() - { - return 0; - } - - public static int LastMessageTimestampEncodingOffset() - { - return 16; - } - - public static int LastMessageTimestampEncodingLength() - { - return 8; - } - - public static string LastMessageTimestampMetaAttribute(MetaAttribute metaAttribute) - { - switch (metaAttribute) - { - case MetaAttribute.EPOCH: return "unix"; - case MetaAttribute.TIME_UNIT: return "nanosecond"; - case MetaAttribute.SEMANTIC_TYPE: return ""; - case MetaAttribute.PRESENCE: return "required"; - } - - return ""; - } - - public static long LastMessageTimestampNullValue() - { - return -9223372036854775808L; - } - - public static long LastMessageTimestampMinValue() - { - return -9223372036854775807L; - } - - public static long LastMessageTimestampMaxValue() - { - return 9223372036854775807L; - } - - public long LastMessageTimestamp() - { - return _buffer.GetLong(_offset + 16, ByteOrder.LittleEndian); - } - - - public static int LeadershipTimestampId() - { - return 4; - } - - public static int LeadershipTimestampSinceVersion() - { - return 0; - } - - public static int LeadershipTimestampEncodingOffset() - { - return 24; - } - - public static int LeadershipTimestampEncodingLength() - { - return 8; - } - - public static string LeadershipTimestampMetaAttribute(MetaAttribute metaAttribute) - { - switch (metaAttribute) - { - case MetaAttribute.EPOCH: return "unix"; - case MetaAttribute.TIME_UNIT: return "nanosecond"; - case MetaAttribute.SEMANTIC_TYPE: return ""; - case MetaAttribute.PRESENCE: return "required"; - } - - return ""; - } - - public static long LeadershipTimestampNullValue() - { - return -9223372036854775808L; - } - - public static long LeadershipTimestampMinValue() - { - return -9223372036854775807L; - } - - public static long LeadershipTimestampMaxValue() - { - return 9223372036854775807L; - } - - public long LeadershipTimestamp() - { - return _buffer.GetLong(_offset + 24, ByteOrder.LittleEndian); - } - - - public static int LeadershipTermIdId() - { - return 5; - } - - public static int LeadershipTermIdSinceVersion() - { - return 0; - } - - public static int LeadershipTermIdEncodingOffset() - { - return 32; - } - - public static int LeadershipTermIdEncodingLength() - { - return 8; - } - - public static string LeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) - { - switch (metaAttribute) - { - case MetaAttribute.EPOCH: return "unix"; - case MetaAttribute.TIME_UNIT: return "nanosecond"; - case MetaAttribute.SEMANTIC_TYPE: return ""; - case MetaAttribute.PRESENCE: return "required"; - } - - return ""; - } - - public static long LeadershipTermIdNullValue() - { - return -9223372036854775808L; - } - - public static long LeadershipTermIdMinValue() - { - return -9223372036854775807L; - } - - public static long LeadershipTermIdMaxValue() - { - return 9223372036854775807L; - } - - public long LeadershipTermId() - { - return _buffer.GetLong(_offset + 32, ByteOrder.LittleEndian); - } - - public static int LeaderMemberIdId() { - return 6; + return 2; } public static int LeaderMemberIdSinceVersion() @@ -370,7 +154,7 @@ public static int LeaderMemberIdSinceVersion() public static int LeaderMemberIdEncodingOffset() { - return 40; + return 8; } public static int LeaderMemberIdEncodingLength() @@ -408,13 +192,13 @@ public static int LeaderMemberIdMaxValue() public int LeaderMemberId() { - return _buffer.GetInt(_offset + 40, ByteOrder.LittleEndian); + return _buffer.GetInt(_offset + 8, ByteOrder.LittleEndian); } public static int MemberEndpointsId() { - return 7; + return 3; } public static int MemberEndpointsSinceVersion() @@ -521,32 +305,12 @@ public StringBuilder AppendTo(StringBuilder builder) builder.Append("ClusterSessionId="); builder.Append(ClusterSessionId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='lastCorrelationId', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("LastCorrelationId="); - builder.Append(LastCorrelationId()); - builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='lastMessageTimestamp', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='time_t', referencedName='null', description='Epoch time in milliseconds since 1 Jan 1970 UTC', id=-1, version=0, deprecated=0, encodedLength=8, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("LastMessageTimestamp="); - builder.Append(LastMessageTimestamp()); - builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='leadershipTimestamp', referencedName='null', description='null', id=4, version=0, deprecated=0, encodedLength=0, offset=24, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='time_t', referencedName='null', description='Epoch time in milliseconds since 1 Jan 1970 UTC', id=-1, version=0, deprecated=0, encodedLength=8, offset=24, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("LeadershipTimestamp="); - builder.Append(LeadershipTimestamp()); - builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='leadershipTermId', referencedName='null', description='null', id=5, version=0, deprecated=0, encodedLength=0, offset=32, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=32, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("LeadershipTermId="); - builder.Append(LeadershipTermId()); - builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='leaderMemberId', referencedName='null', description='null', id=6, version=0, deprecated=0, encodedLength=0, offset=40, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=40, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='leaderMemberId', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("LeaderMemberId="); builder.Append(LeaderMemberId()); builder.Append('|'); - //Token{signal=BEGIN_VAR_DATA, name='memberEndpoints', referencedName='null', description='null', id=7, version=0, deprecated=0, encodedLength=0, offset=44, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_VAR_DATA, name='memberEndpoints', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=12, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("MemberEndpoints="); builder.Append(MemberEndpoints()); diff --git a/src/Adaptive.Cluster/Codecs/NewLeaderEventEncoder.cs b/src/Adaptive.Cluster/Codecs/NewLeaderEventEncoder.cs index deeeb66a..6c885728 100644 --- a/src/Adaptive.Cluster/Codecs/NewLeaderEventEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/NewLeaderEventEncoder.cs @@ -9,7 +9,7 @@ namespace Adaptive.Cluster.Codecs { public class NewLeaderEventEncoder { - public const ushort BLOCK_LENGTH = 44; + public const ushort BLOCK_LENGTH = 12; public const ushort TEMPLATE_ID = 6; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; @@ -128,137 +128,9 @@ public NewLeaderEventEncoder ClusterSessionId(long value) } - public static int LastCorrelationIdEncodingOffset() - { - return 8; - } - - public static int LastCorrelationIdEncodingLength() - { - return 8; - } - - public static long LastCorrelationIdNullValue() - { - return -9223372036854775808L; - } - - public static long LastCorrelationIdMinValue() - { - return -9223372036854775807L; - } - - public static long LastCorrelationIdMaxValue() - { - return 9223372036854775807L; - } - - public NewLeaderEventEncoder LastCorrelationId(long value) - { - _buffer.PutLong(_offset + 8, value, ByteOrder.LittleEndian); - return this; - } - - - public static int LastMessageTimestampEncodingOffset() - { - return 16; - } - - public static int LastMessageTimestampEncodingLength() - { - return 8; - } - - public static long LastMessageTimestampNullValue() - { - return -9223372036854775808L; - } - - public static long LastMessageTimestampMinValue() - { - return -9223372036854775807L; - } - - public static long LastMessageTimestampMaxValue() - { - return 9223372036854775807L; - } - - public NewLeaderEventEncoder LastMessageTimestamp(long value) - { - _buffer.PutLong(_offset + 16, value, ByteOrder.LittleEndian); - return this; - } - - - public static int LeadershipTimestampEncodingOffset() - { - return 24; - } - - public static int LeadershipTimestampEncodingLength() - { - return 8; - } - - public static long LeadershipTimestampNullValue() - { - return -9223372036854775808L; - } - - public static long LeadershipTimestampMinValue() - { - return -9223372036854775807L; - } - - public static long LeadershipTimestampMaxValue() - { - return 9223372036854775807L; - } - - public NewLeaderEventEncoder LeadershipTimestamp(long value) - { - _buffer.PutLong(_offset + 24, value, ByteOrder.LittleEndian); - return this; - } - - - public static int LeadershipTermIdEncodingOffset() - { - return 32; - } - - public static int LeadershipTermIdEncodingLength() - { - return 8; - } - - public static long LeadershipTermIdNullValue() - { - return -9223372036854775808L; - } - - public static long LeadershipTermIdMinValue() - { - return -9223372036854775807L; - } - - public static long LeadershipTermIdMaxValue() - { - return 9223372036854775807L; - } - - public NewLeaderEventEncoder LeadershipTermId(long value) - { - _buffer.PutLong(_offset + 32, value, ByteOrder.LittleEndian); - return this; - } - - public static int LeaderMemberIdEncodingOffset() { - return 40; + return 8; } public static int LeaderMemberIdEncodingLength() @@ -283,14 +155,14 @@ public static int LeaderMemberIdMaxValue() public NewLeaderEventEncoder LeaderMemberId(int value) { - _buffer.PutInt(_offset + 40, value, ByteOrder.LittleEndian); + _buffer.PutInt(_offset + 8, value, ByteOrder.LittleEndian); return this; } public static int MemberEndpointsId() { - return 7; + return 3; } public static string MemberEndpointsCharacterEncoding() diff --git a/src/Adaptive.Cluster/Codecs/NewLeadershipTermDecoder.cs b/src/Adaptive.Cluster/Codecs/NewLeadershipTermDecoder.cs index 6285cb1f..cef883d0 100644 --- a/src/Adaptive.Cluster/Codecs/NewLeadershipTermDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/NewLeadershipTermDecoder.cs @@ -9,7 +9,7 @@ namespace Adaptive.Cluster.Codecs { public class NewLeadershipTermDecoder { - public const ushort BLOCK_LENGTH = 24; + public const ushort BLOCK_LENGTH = 32; public const ushort TEMPLATE_ID = 53; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; @@ -88,11 +88,65 @@ public void Limit(int limit) this._limit = limit; } - public static int LogPositionId() + public static int LogLeadershipTermIdId() { return 1; } + public static int LogLeadershipTermIdSinceVersion() + { + return 0; + } + + public static int LogLeadershipTermIdEncodingOffset() + { + return 0; + } + + public static int LogLeadershipTermIdEncodingLength() + { + return 8; + } + + public static string LogLeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long LogLeadershipTermIdNullValue() + { + return -9223372036854775808L; + } + + public static long LogLeadershipTermIdMinValue() + { + return -9223372036854775807L; + } + + public static long LogLeadershipTermIdMaxValue() + { + return 9223372036854775807L; + } + + public long LogLeadershipTermId() + { + return _buffer.GetLong(_offset + 0, ByteOrder.LittleEndian); + } + + + public static int LogPositionId() + { + return 2; + } + public static int LogPositionSinceVersion() { return 0; @@ -100,7 +154,7 @@ public static int LogPositionSinceVersion() public static int LogPositionEncodingOffset() { - return 0; + return 8; } public static int LogPositionEncodingLength() @@ -138,13 +192,13 @@ public static long LogPositionMaxValue() public long LogPosition() { - return _buffer.GetLong(_offset + 0, ByteOrder.LittleEndian); + return _buffer.GetLong(_offset + 8, ByteOrder.LittleEndian); } public static int LeadershipTermIdId() { - return 2; + return 3; } public static int LeadershipTermIdSinceVersion() @@ -154,7 +208,7 @@ public static int LeadershipTermIdSinceVersion() public static int LeadershipTermIdEncodingOffset() { - return 8; + return 16; } public static int LeadershipTermIdEncodingLength() @@ -192,13 +246,13 @@ public static long LeadershipTermIdMaxValue() public long LeadershipTermId() { - return _buffer.GetLong(_offset + 8, ByteOrder.LittleEndian); + return _buffer.GetLong(_offset + 16, ByteOrder.LittleEndian); } public static int LeaderMemberIdId() { - return 3; + return 4; } public static int LeaderMemberIdSinceVersion() @@ -208,7 +262,7 @@ public static int LeaderMemberIdSinceVersion() public static int LeaderMemberIdEncodingOffset() { - return 16; + return 24; } public static int LeaderMemberIdEncodingLength() @@ -246,13 +300,13 @@ public static int LeaderMemberIdMaxValue() public int LeaderMemberId() { - return _buffer.GetInt(_offset + 16, ByteOrder.LittleEndian); + return _buffer.GetInt(_offset + 24, ByteOrder.LittleEndian); } public static int LogSessionIdId() { - return 4; + return 5; } public static int LogSessionIdSinceVersion() @@ -262,7 +316,7 @@ public static int LogSessionIdSinceVersion() public static int LogSessionIdEncodingOffset() { - return 20; + return 28; } public static int LogSessionIdEncodingLength() @@ -300,7 +354,7 @@ public static int LogSessionIdMaxValue() public int LogSessionId() { - return _buffer.GetInt(_offset + 20, ByteOrder.LittleEndian); + return _buffer.GetInt(_offset + 28, ByteOrder.LittleEndian); } @@ -333,23 +387,28 @@ public StringBuilder AppendTo(StringBuilder builder) } builder.Append(BLOCK_LENGTH); builder.Append("):"); - //Token{signal=BEGIN_FIELD, name='logPosition', referencedName='null', description='null', id=1, version=0, deprecated=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='logLeadershipTermId', referencedName='null', description='null', id=1, version=0, deprecated=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=0, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LogLeadershipTermId="); + builder.Append(LogLeadershipTermId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='logPosition', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("LogPosition="); builder.Append(LogPosition()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='leadershipTermId', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='leadershipTermId', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("LeadershipTermId="); builder.Append(LeadershipTermId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='leaderMemberId', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='leaderMemberId', referencedName='null', description='null', id=4, version=0, deprecated=0, encodedLength=0, offset=24, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=24, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("LeaderMemberId="); builder.Append(LeaderMemberId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='logSessionId', referencedName='null', description='null', id=4, version=0, deprecated=0, encodedLength=0, offset=20, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=20, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='logSessionId', referencedName='null', description='null', id=5, version=0, deprecated=0, encodedLength=0, offset=28, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=28, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("LogSessionId="); builder.Append(LogSessionId()); diff --git a/src/Adaptive.Cluster/Codecs/NewLeadershipTermEncoder.cs b/src/Adaptive.Cluster/Codecs/NewLeadershipTermEncoder.cs index f8dece5a..33e64918 100644 --- a/src/Adaptive.Cluster/Codecs/NewLeadershipTermEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/NewLeadershipTermEncoder.cs @@ -9,7 +9,7 @@ namespace Adaptive.Cluster.Codecs { public class NewLeadershipTermEncoder { - public const ushort BLOCK_LENGTH = 24; + public const ushort BLOCK_LENGTH = 32; public const ushort TEMPLATE_ID = 53; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; @@ -96,11 +96,43 @@ public void Limit(int limit) this._limit = limit; } - public static int LogPositionEncodingOffset() + public static int LogLeadershipTermIdEncodingOffset() { return 0; } + public static int LogLeadershipTermIdEncodingLength() + { + return 8; + } + + public static long LogLeadershipTermIdNullValue() + { + return -9223372036854775808L; + } + + public static long LogLeadershipTermIdMinValue() + { + return -9223372036854775807L; + } + + public static long LogLeadershipTermIdMaxValue() + { + return 9223372036854775807L; + } + + public NewLeadershipTermEncoder LogLeadershipTermId(long value) + { + _buffer.PutLong(_offset + 0, value, ByteOrder.LittleEndian); + return this; + } + + + public static int LogPositionEncodingOffset() + { + return 8; + } + public static int LogPositionEncodingLength() { return 8; @@ -123,14 +155,14 @@ public static long LogPositionMaxValue() public NewLeadershipTermEncoder LogPosition(long value) { - _buffer.PutLong(_offset + 0, value, ByteOrder.LittleEndian); + _buffer.PutLong(_offset + 8, value, ByteOrder.LittleEndian); return this; } public static int LeadershipTermIdEncodingOffset() { - return 8; + return 16; } public static int LeadershipTermIdEncodingLength() @@ -155,14 +187,14 @@ public static long LeadershipTermIdMaxValue() public NewLeadershipTermEncoder LeadershipTermId(long value) { - _buffer.PutLong(_offset + 8, value, ByteOrder.LittleEndian); + _buffer.PutLong(_offset + 16, value, ByteOrder.LittleEndian); return this; } public static int LeaderMemberIdEncodingOffset() { - return 16; + return 24; } public static int LeaderMemberIdEncodingLength() @@ -187,14 +219,14 @@ public static int LeaderMemberIdMaxValue() public NewLeadershipTermEncoder LeaderMemberId(int value) { - _buffer.PutInt(_offset + 16, value, ByteOrder.LittleEndian); + _buffer.PutInt(_offset + 24, value, ByteOrder.LittleEndian); return this; } public static int LogSessionIdEncodingOffset() { - return 20; + return 28; } public static int LogSessionIdEncodingLength() @@ -219,7 +251,7 @@ public static int LogSessionIdMaxValue() public NewLeadershipTermEncoder LogSessionId(int value) { - _buffer.PutInt(_offset + 20, value, ByteOrder.LittleEndian); + _buffer.PutInt(_offset + 28, value, ByteOrder.LittleEndian); return this; } diff --git a/src/Adaptive.Cluster/Codecs/NewLeadershipTermEventDecoder.cs b/src/Adaptive.Cluster/Codecs/NewLeadershipTermEventDecoder.cs new file mode 100644 index 00000000..e9cdefc6 --- /dev/null +++ b/src/Adaptive.Cluster/Codecs/NewLeadershipTermEventDecoder.cs @@ -0,0 +1,420 @@ +/* Generated SBE (Simple Binary Encoding) message codec */ +using System; +using System.Text; +using System.Collections.Generic; +using Adaptive.Agrona; + + +namespace Adaptive.Cluster.Codecs { + +public class NewLeadershipTermEventDecoder +{ + public const ushort BLOCK_LENGTH = 32; + public const ushort TEMPLATE_ID = 24; + public const ushort SCHEMA_ID = 1; + public const ushort SCHEMA_VERSION = 1; + + private NewLeadershipTermEventDecoder _parentMessage; + private IDirectBuffer _buffer; + protected int _offset; + protected int _limit; + protected int _actingBlockLength; + protected int _actingVersion; + + public NewLeadershipTermEventDecoder() + { + _parentMessage = this; + } + + public ushort SbeBlockLength() + { + return BLOCK_LENGTH; + } + + public ushort SbeTemplateId() + { + return TEMPLATE_ID; + } + + public ushort SbeSchemaId() + { + return SCHEMA_ID; + } + + public ushort SbeSchemaVersion() + { + return SCHEMA_VERSION; + } + + public string SbeSemanticType() + { + return ""; + } + + public IDirectBuffer Buffer() + { + return _buffer; + } + + public int Offset() + { + return _offset; + } + + public NewLeadershipTermEventDecoder Wrap( + IDirectBuffer buffer, int offset, int actingBlockLength, int actingVersion) + { + this._buffer = buffer; + this._offset = offset; + this._actingBlockLength = actingBlockLength; + this._actingVersion = actingVersion; + Limit(offset + actingBlockLength); + + return this; + } + + public int EncodedLength() + { + return _limit - _offset; + } + + public int Limit() + { + return _limit; + } + + public void Limit(int limit) + { + this._limit = limit; + } + + public static int LeadershipTermIdId() + { + return 1; + } + + public static int LeadershipTermIdSinceVersion() + { + return 0; + } + + public static int LeadershipTermIdEncodingOffset() + { + return 0; + } + + public static int LeadershipTermIdEncodingLength() + { + return 8; + } + + public static string LeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long LeadershipTermIdNullValue() + { + return -9223372036854775808L; + } + + public static long LeadershipTermIdMinValue() + { + return -9223372036854775807L; + } + + public static long LeadershipTermIdMaxValue() + { + return 9223372036854775807L; + } + + public long LeadershipTermId() + { + return _buffer.GetLong(_offset + 0, ByteOrder.LittleEndian); + } + + + public static int LogPositionId() + { + return 2; + } + + public static int LogPositionSinceVersion() + { + return 0; + } + + public static int LogPositionEncodingOffset() + { + return 8; + } + + public static int LogPositionEncodingLength() + { + return 8; + } + + public static string LogPositionMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long LogPositionNullValue() + { + return -9223372036854775808L; + } + + public static long LogPositionMinValue() + { + return -9223372036854775807L; + } + + public static long LogPositionMaxValue() + { + return 9223372036854775807L; + } + + public long LogPosition() + { + return _buffer.GetLong(_offset + 8, ByteOrder.LittleEndian); + } + + + public static int TimestampId() + { + return 3; + } + + public static int TimestampSinceVersion() + { + return 0; + } + + public static int TimestampEncodingOffset() + { + return 16; + } + + public static int TimestampEncodingLength() + { + return 8; + } + + public static string TimestampMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long TimestampNullValue() + { + return -9223372036854775808L; + } + + public static long TimestampMinValue() + { + return -9223372036854775807L; + } + + public static long TimestampMaxValue() + { + return 9223372036854775807L; + } + + public long Timestamp() + { + return _buffer.GetLong(_offset + 16, ByteOrder.LittleEndian); + } + + + public static int LeaderMemberIdId() + { + return 4; + } + + public static int LeaderMemberIdSinceVersion() + { + return 0; + } + + public static int LeaderMemberIdEncodingOffset() + { + return 24; + } + + public static int LeaderMemberIdEncodingLength() + { + return 4; + } + + public static string LeaderMemberIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static int LeaderMemberIdNullValue() + { + return -2147483648; + } + + public static int LeaderMemberIdMinValue() + { + return -2147483647; + } + + public static int LeaderMemberIdMaxValue() + { + return 2147483647; + } + + public int LeaderMemberId() + { + return _buffer.GetInt(_offset + 24, ByteOrder.LittleEndian); + } + + + public static int LogSessionIdId() + { + return 5; + } + + public static int LogSessionIdSinceVersion() + { + return 0; + } + + public static int LogSessionIdEncodingOffset() + { + return 28; + } + + public static int LogSessionIdEncodingLength() + { + return 4; + } + + public static string LogSessionIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static int LogSessionIdNullValue() + { + return -2147483648; + } + + public static int LogSessionIdMinValue() + { + return -2147483647; + } + + public static int LogSessionIdMaxValue() + { + return 2147483647; + } + + public int LogSessionId() + { + return _buffer.GetInt(_offset + 28, ByteOrder.LittleEndian); + } + + + + public override string ToString() + { + return AppendTo(new StringBuilder(100)).ToString(); + } + + public StringBuilder AppendTo(StringBuilder builder) + { + int originalLimit = Limit(); + Limit(_offset + _actingBlockLength); + builder.Append("[NewLeadershipTermEvent](sbeTemplateId="); + builder.Append(TEMPLATE_ID); + builder.Append("|sbeSchemaId="); + builder.Append(SCHEMA_ID); + builder.Append("|sbeSchemaVersion="); + if (_parentMessage._actingVersion != SCHEMA_VERSION) + { + builder.Append(_parentMessage._actingVersion); + builder.Append('/'); + } + builder.Append(SCHEMA_VERSION); + builder.Append("|sbeBlockLength="); + if (_actingBlockLength != BLOCK_LENGTH) + { + builder.Append(_actingBlockLength); + builder.Append('/'); + } + builder.Append(BLOCK_LENGTH); + builder.Append("):"); + //Token{signal=BEGIN_FIELD, name='leadershipTermId', referencedName='null', description='null', id=1, version=0, deprecated=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=0, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LeadershipTermId="); + builder.Append(LeadershipTermId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='logPosition', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LogPosition="); + builder.Append(LogPosition()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='timestamp', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='time_t', referencedName='null', description='Epoch time in milliseconds since 1 Jan 1970 UTC', id=-1, version=0, deprecated=0, encodedLength=8, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("Timestamp="); + builder.Append(Timestamp()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='leaderMemberId', referencedName='null', description='null', id=4, version=0, deprecated=0, encodedLength=0, offset=24, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=24, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LeaderMemberId="); + builder.Append(LeaderMemberId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='logSessionId', referencedName='null', description='null', id=5, version=0, deprecated=0, encodedLength=0, offset=28, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=28, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LogSessionId="); + builder.Append(LogSessionId()); + + Limit(originalLimit); + + return builder; + } +} +} diff --git a/src/Adaptive.Cluster/Codecs/NewLeadershipTermEventEncoder.cs b/src/Adaptive.Cluster/Codecs/NewLeadershipTermEventEncoder.cs new file mode 100644 index 00000000..7ac0a408 --- /dev/null +++ b/src/Adaptive.Cluster/Codecs/NewLeadershipTermEventEncoder.cs @@ -0,0 +1,273 @@ +/* Generated SBE (Simple Binary Encoding) message codec */ +using System; +using System.Text; +using System.Collections.Generic; +using Adaptive.Agrona; + + +namespace Adaptive.Cluster.Codecs { + +public class NewLeadershipTermEventEncoder +{ + public const ushort BLOCK_LENGTH = 32; + public const ushort TEMPLATE_ID = 24; + public const ushort SCHEMA_ID = 1; + public const ushort SCHEMA_VERSION = 1; + + private NewLeadershipTermEventEncoder _parentMessage; + private IMutableDirectBuffer _buffer; + protected int _offset; + protected int _limit; + + public NewLeadershipTermEventEncoder() + { + _parentMessage = this; + } + + public ushort SbeBlockLength() + { + return BLOCK_LENGTH; + } + + public ushort SbeTemplateId() + { + return TEMPLATE_ID; + } + + public ushort SbeSchemaId() + { + return SCHEMA_ID; + } + + public ushort SbeSchemaVersion() + { + return SCHEMA_VERSION; + } + + public string SbeSemanticType() + { + return ""; + } + + public IMutableDirectBuffer Buffer() + { + return _buffer; + } + + public int Offset() + { + return _offset; + } + + public NewLeadershipTermEventEncoder Wrap(IMutableDirectBuffer buffer, int offset) + { + this._buffer = buffer; + this._offset = offset; + Limit(offset + BLOCK_LENGTH); + + return this; + } + + public NewLeadershipTermEventEncoder WrapAndApplyHeader( + IMutableDirectBuffer buffer, int offset, MessageHeaderEncoder headerEncoder) + { + headerEncoder + .Wrap(buffer, offset) + .BlockLength(BLOCK_LENGTH) + .TemplateId(TEMPLATE_ID) + .SchemaId(SCHEMA_ID) + .Version(SCHEMA_VERSION); + + return Wrap(buffer, offset + MessageHeaderEncoder.ENCODED_LENGTH); + } + + public int EncodedLength() + { + return _limit - _offset; + } + + public int Limit() + { + return _limit; + } + + public void Limit(int limit) + { + this._limit = limit; + } + + public static int LeadershipTermIdEncodingOffset() + { + return 0; + } + + public static int LeadershipTermIdEncodingLength() + { + return 8; + } + + public static long LeadershipTermIdNullValue() + { + return -9223372036854775808L; + } + + public static long LeadershipTermIdMinValue() + { + return -9223372036854775807L; + } + + public static long LeadershipTermIdMaxValue() + { + return 9223372036854775807L; + } + + public NewLeadershipTermEventEncoder LeadershipTermId(long value) + { + _buffer.PutLong(_offset + 0, value, ByteOrder.LittleEndian); + return this; + } + + + public static int LogPositionEncodingOffset() + { + return 8; + } + + public static int LogPositionEncodingLength() + { + return 8; + } + + public static long LogPositionNullValue() + { + return -9223372036854775808L; + } + + public static long LogPositionMinValue() + { + return -9223372036854775807L; + } + + public static long LogPositionMaxValue() + { + return 9223372036854775807L; + } + + public NewLeadershipTermEventEncoder LogPosition(long value) + { + _buffer.PutLong(_offset + 8, value, ByteOrder.LittleEndian); + return this; + } + + + public static int TimestampEncodingOffset() + { + return 16; + } + + public static int TimestampEncodingLength() + { + return 8; + } + + public static long TimestampNullValue() + { + return -9223372036854775808L; + } + + public static long TimestampMinValue() + { + return -9223372036854775807L; + } + + public static long TimestampMaxValue() + { + return 9223372036854775807L; + } + + public NewLeadershipTermEventEncoder Timestamp(long value) + { + _buffer.PutLong(_offset + 16, value, ByteOrder.LittleEndian); + return this; + } + + + public static int LeaderMemberIdEncodingOffset() + { + return 24; + } + + public static int LeaderMemberIdEncodingLength() + { + return 4; + } + + public static int LeaderMemberIdNullValue() + { + return -2147483648; + } + + public static int LeaderMemberIdMinValue() + { + return -2147483647; + } + + public static int LeaderMemberIdMaxValue() + { + return 2147483647; + } + + public NewLeadershipTermEventEncoder LeaderMemberId(int value) + { + _buffer.PutInt(_offset + 24, value, ByteOrder.LittleEndian); + return this; + } + + + public static int LogSessionIdEncodingOffset() + { + return 28; + } + + public static int LogSessionIdEncodingLength() + { + return 4; + } + + public static int LogSessionIdNullValue() + { + return -2147483648; + } + + public static int LogSessionIdMinValue() + { + return -2147483647; + } + + public static int LogSessionIdMaxValue() + { + return 2147483647; + } + + public NewLeadershipTermEventEncoder LogSessionId(int value) + { + _buffer.PutInt(_offset + 28, value, ByteOrder.LittleEndian); + return this; + } + + + + public override string ToString() + { + return AppendTo(new StringBuilder(100)).ToString(); + } + + public StringBuilder AppendTo(StringBuilder builder) + { + NewLeadershipTermEventDecoder writer = new NewLeadershipTermEventDecoder(); + writer.Wrap(_buffer, _offset, BLOCK_LENGTH, SCHEMA_VERSION); + + return writer.AppendTo(builder); + } +} +} diff --git a/src/Adaptive.Cluster/Codecs/RecordingLogDecoder.cs b/src/Adaptive.Cluster/Codecs/RecordingLogDecoder.cs new file mode 100644 index 00000000..2b3bc39d --- /dev/null +++ b/src/Adaptive.Cluster/Codecs/RecordingLogDecoder.cs @@ -0,0 +1,866 @@ +/* Generated SBE (Simple Binary Encoding) message codec */ +using System; +using System.Text; +using System.Collections.Generic; +using Adaptive.Agrona; + + +namespace Adaptive.Cluster.Codecs { + +public class RecordingLogDecoder +{ + public const ushort BLOCK_LENGTH = 20; + public const ushort TEMPLATE_ID = 64; + public const ushort SCHEMA_ID = 1; + public const ushort SCHEMA_VERSION = 1; + + private RecordingLogDecoder _parentMessage; + private IDirectBuffer _buffer; + protected int _offset; + protected int _limit; + protected int _actingBlockLength; + protected int _actingVersion; + + public RecordingLogDecoder() + { + _parentMessage = this; + } + + public ushort SbeBlockLength() + { + return BLOCK_LENGTH; + } + + public ushort SbeTemplateId() + { + return TEMPLATE_ID; + } + + public ushort SbeSchemaId() + { + return SCHEMA_ID; + } + + public ushort SbeSchemaVersion() + { + return SCHEMA_VERSION; + } + + public string SbeSemanticType() + { + return ""; + } + + public IDirectBuffer Buffer() + { + return _buffer; + } + + public int Offset() + { + return _offset; + } + + public RecordingLogDecoder Wrap( + IDirectBuffer buffer, int offset, int actingBlockLength, int actingVersion) + { + this._buffer = buffer; + this._offset = offset; + this._actingBlockLength = actingBlockLength; + this._actingVersion = actingVersion; + Limit(offset + actingBlockLength); + + return this; + } + + public int EncodedLength() + { + return _limit - _offset; + } + + public int Limit() + { + return _limit; + } + + public void Limit(int limit) + { + this._limit = limit; + } + + public static int CorrelationIdId() + { + return 1; + } + + public static int CorrelationIdSinceVersion() + { + return 0; + } + + public static int CorrelationIdEncodingOffset() + { + return 0; + } + + public static int CorrelationIdEncodingLength() + { + return 8; + } + + public static string CorrelationIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long CorrelationIdNullValue() + { + return -9223372036854775808L; + } + + public static long CorrelationIdMinValue() + { + return -9223372036854775807L; + } + + public static long CorrelationIdMaxValue() + { + return 9223372036854775807L; + } + + public long CorrelationId() + { + return _buffer.GetLong(_offset + 0, ByteOrder.LittleEndian); + } + + + public static int RequestMemberIdId() + { + return 2; + } + + public static int RequestMemberIdSinceVersion() + { + return 0; + } + + public static int RequestMemberIdEncodingOffset() + { + return 8; + } + + public static int RequestMemberIdEncodingLength() + { + return 4; + } + + public static string RequestMemberIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static int RequestMemberIdNullValue() + { + return -2147483648; + } + + public static int RequestMemberIdMinValue() + { + return -2147483647; + } + + public static int RequestMemberIdMaxValue() + { + return 2147483647; + } + + public int RequestMemberId() + { + return _buffer.GetInt(_offset + 8, ByteOrder.LittleEndian); + } + + + public static int LeaderMemberIdId() + { + return 3; + } + + public static int LeaderMemberIdSinceVersion() + { + return 0; + } + + public static int LeaderMemberIdEncodingOffset() + { + return 12; + } + + public static int LeaderMemberIdEncodingLength() + { + return 4; + } + + public static string LeaderMemberIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static int LeaderMemberIdNullValue() + { + return -2147483648; + } + + public static int LeaderMemberIdMinValue() + { + return -2147483647; + } + + public static int LeaderMemberIdMaxValue() + { + return 2147483647; + } + + public int LeaderMemberId() + { + return _buffer.GetInt(_offset + 12, ByteOrder.LittleEndian); + } + + + private EntriesDecoder _Entries = new EntriesDecoder(); + + public static long EntriesDecoderId() + { + return 4; + } + + public static int EntriesDecoderSinceVersion() + { + return 0; + } + + public EntriesDecoder Entries() + { + _Entries.Wrap(_parentMessage, _buffer); + return _Entries; + } + + public class EntriesDecoder + { + private static int HEADER_SIZE = 4; + private GroupSizeEncodingDecoder _dimensions = new GroupSizeEncodingDecoder(); + private RecordingLogDecoder _parentMessage; + private IDirectBuffer _buffer; + private int _count; + private int _index; + private int _offset; + private int _blockLength; + + public void Wrap( + RecordingLogDecoder parentMessage, IDirectBuffer buffer) + { + this._parentMessage = parentMessage; + this._buffer = buffer; + _dimensions.Wrap(buffer, parentMessage.Limit()); + _blockLength = _dimensions.BlockLength(); + _count = _dimensions.NumInGroup(); + _index = -1; + parentMessage.Limit(parentMessage.Limit() + HEADER_SIZE); + } + + public static int SbeHeaderSize() + { + return HEADER_SIZE; + } + + public static int SbeBlockLength() + { + return 64; + } + + public int ActingBlockLength() + { + return _blockLength; + } + + public int Count() + { + return _count; + } + + public bool HasNext() + { + return (_index + 1) < _count; + } + + public EntriesDecoder Next() + { + if (_index + 1 >= _count) + { + throw new IndexOutOfRangeException(); + } + + _offset = _parentMessage.Limit(); + _parentMessage.Limit(_offset + _blockLength); + ++_index; + + return this; + } + + public static int RecordingIdId() + { + return 5; + } + + public static int RecordingIdSinceVersion() + { + return 0; + } + + public static int RecordingIdEncodingOffset() + { + return 0; + } + + public static int RecordingIdEncodingLength() + { + return 8; + } + + public static string RecordingIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long RecordingIdNullValue() + { + return -9223372036854775808L; + } + + public static long RecordingIdMinValue() + { + return -9223372036854775807L; + } + + public static long RecordingIdMaxValue() + { + return 9223372036854775807L; + } + + public long RecordingId() + { + return _buffer.GetLong(_offset + 0, ByteOrder.LittleEndian); + } + + + public static int LeadershipTermIdId() + { + return 6; + } + + public static int LeadershipTermIdSinceVersion() + { + return 0; + } + + public static int LeadershipTermIdEncodingOffset() + { + return 8; + } + + public static int LeadershipTermIdEncodingLength() + { + return 8; + } + + public static string LeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long LeadershipTermIdNullValue() + { + return -9223372036854775808L; + } + + public static long LeadershipTermIdMinValue() + { + return -9223372036854775807L; + } + + public static long LeadershipTermIdMaxValue() + { + return 9223372036854775807L; + } + + public long LeadershipTermId() + { + return _buffer.GetLong(_offset + 8, ByteOrder.LittleEndian); + } + + + public static int TermBaseLogPositionId() + { + return 7; + } + + public static int TermBaseLogPositionSinceVersion() + { + return 0; + } + + public static int TermBaseLogPositionEncodingOffset() + { + return 16; + } + + public static int TermBaseLogPositionEncodingLength() + { + return 8; + } + + public static string TermBaseLogPositionMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long TermBaseLogPositionNullValue() + { + return -9223372036854775808L; + } + + public static long TermBaseLogPositionMinValue() + { + return -9223372036854775807L; + } + + public static long TermBaseLogPositionMaxValue() + { + return 9223372036854775807L; + } + + public long TermBaseLogPosition() + { + return _buffer.GetLong(_offset + 16, ByteOrder.LittleEndian); + } + + + public static int LogPositionId() + { + return 8; + } + + public static int LogPositionSinceVersion() + { + return 0; + } + + public static int LogPositionEncodingOffset() + { + return 24; + } + + public static int LogPositionEncodingLength() + { + return 8; + } + + public static string LogPositionMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long LogPositionNullValue() + { + return -9223372036854775808L; + } + + public static long LogPositionMinValue() + { + return -9223372036854775807L; + } + + public static long LogPositionMaxValue() + { + return 9223372036854775807L; + } + + public long LogPosition() + { + return _buffer.GetLong(_offset + 24, ByteOrder.LittleEndian); + } + + + public static int TimestampId() + { + return 9; + } + + public static int TimestampSinceVersion() + { + return 0; + } + + public static int TimestampEncodingOffset() + { + return 32; + } + + public static int TimestampEncodingLength() + { + return 8; + } + + public static string TimestampMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long TimestampNullValue() + { + return -9223372036854775808L; + } + + public static long TimestampMinValue() + { + return -9223372036854775807L; + } + + public static long TimestampMaxValue() + { + return 9223372036854775807L; + } + + public long Timestamp() + { + return _buffer.GetLong(_offset + 32, ByteOrder.LittleEndian); + } + + + public static int ServiceIdId() + { + return 10; + } + + public static int ServiceIdSinceVersion() + { + return 0; + } + + public static int ServiceIdEncodingOffset() + { + return 40; + } + + public static int ServiceIdEncodingLength() + { + return 4; + } + + public static string ServiceIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static int ServiceIdNullValue() + { + return -2147483648; + } + + public static int ServiceIdMinValue() + { + return -2147483647; + } + + public static int ServiceIdMaxValue() + { + return 2147483647; + } + + public int ServiceId() + { + return _buffer.GetInt(_offset + 40, ByteOrder.LittleEndian); + } + + + public static int EntryTypeId() + { + return 11; + } + + public static int EntryTypeSinceVersion() + { + return 0; + } + + public static int EntryTypeEncodingOffset() + { + return 44; + } + + public static int EntryTypeEncodingLength() + { + return 4; + } + + public static string EntryTypeMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static int EntryTypeNullValue() + { + return -2147483648; + } + + public static int EntryTypeMinValue() + { + return -2147483647; + } + + public static int EntryTypeMaxValue() + { + return 2147483647; + } + + public int EntryType() + { + return _buffer.GetInt(_offset + 44, ByteOrder.LittleEndian); + } + + + public static int IsCurrentId() + { + return 12; + } + + public static int IsCurrentSinceVersion() + { + return 0; + } + + public static int IsCurrentEncodingOffset() + { + return 48; + } + + public static int IsCurrentEncodingLength() + { + return 4; + } + + public static string IsCurrentMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public BooleanType IsCurrent() + { + return (BooleanType)_buffer.GetInt(_offset + 48, ByteOrder.LittleEndian); + } + + + + public override string ToString() + { + return AppendTo(new StringBuilder(100)).ToString(); + } + + public StringBuilder AppendTo(StringBuilder builder) + { + builder.Append('('); + //Token{signal=BEGIN_FIELD, name='recordingId', referencedName='null', description='null', id=5, version=0, deprecated=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=0, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("RecordingId="); + builder.Append(RecordingId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='leadershipTermId', referencedName='null', description='null', id=6, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LeadershipTermId="); + builder.Append(LeadershipTermId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='termBaseLogPosition', referencedName='null', description='null', id=7, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("TermBaseLogPosition="); + builder.Append(TermBaseLogPosition()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='logPosition', referencedName='null', description='null', id=8, version=0, deprecated=0, encodedLength=0, offset=24, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=24, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LogPosition="); + builder.Append(LogPosition()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='timestamp', referencedName='null', description='null', id=9, version=0, deprecated=0, encodedLength=0, offset=32, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='time_t', referencedName='null', description='Epoch time in milliseconds since 1 Jan 1970 UTC', id=-1, version=0, deprecated=0, encodedLength=8, offset=32, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("Timestamp="); + builder.Append(Timestamp()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='serviceId', referencedName='null', description='null', id=10, version=0, deprecated=0, encodedLength=0, offset=40, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=40, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("ServiceId="); + builder.Append(ServiceId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='entryType', referencedName='null', description='null', id=11, version=0, deprecated=0, encodedLength=0, offset=44, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=44, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("EntryType="); + builder.Append(EntryType()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='isCurrent', referencedName='null', description='null', id=12, version=0, deprecated=0, encodedLength=0, offset=48, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_ENUM, name='BooleanType', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=48, componentTokenCount=4, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='null', timeUnit=null, semanticType='null'}} + builder.Append("IsCurrent="); + builder.Append(IsCurrent()); + builder.Append(')'); + return builder; + } + } + + + public override string ToString() + { + return AppendTo(new StringBuilder(100)).ToString(); + } + + public StringBuilder AppendTo(StringBuilder builder) + { + int originalLimit = Limit(); + Limit(_offset + _actingBlockLength); + builder.Append("[RecordingLog](sbeTemplateId="); + builder.Append(TEMPLATE_ID); + builder.Append("|sbeSchemaId="); + builder.Append(SCHEMA_ID); + builder.Append("|sbeSchemaVersion="); + if (_parentMessage._actingVersion != SCHEMA_VERSION) + { + builder.Append(_parentMessage._actingVersion); + builder.Append('/'); + } + builder.Append(SCHEMA_VERSION); + builder.Append("|sbeBlockLength="); + if (_actingBlockLength != BLOCK_LENGTH) + { + builder.Append(_actingBlockLength); + builder.Append('/'); + } + builder.Append(BLOCK_LENGTH); + builder.Append("):"); + //Token{signal=BEGIN_FIELD, name='correlationId', referencedName='null', description='null', id=1, version=0, deprecated=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=0, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("CorrelationId="); + builder.Append(CorrelationId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='requestMemberId', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("RequestMemberId="); + builder.Append(RequestMemberId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='leaderMemberId', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=12, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=12, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LeaderMemberId="); + builder.Append(LeaderMemberId()); + builder.Append('|'); + //Token{signal=BEGIN_GROUP, name='entries', referencedName='null', description='null', id=4, version=0, deprecated=0, encodedLength=64, offset=20, componentTokenCount=33, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='null', timeUnit=null, semanticType='null'}} + builder.Append("Entries=["); + EntriesDecoder Entries = this.Entries(); + if (Entries.Count() > 0) + { + while (Entries.HasNext()) + { + Entries.Next().AppendTo(builder); + builder.Append(','); + } + builder.Length = builder.Length - 1; + } + builder.Append(']'); + + Limit(originalLimit); + + return builder; + } +} +} diff --git a/src/Adaptive.Cluster/Codecs/RecordingLogEncoder.cs b/src/Adaptive.Cluster/Codecs/RecordingLogEncoder.cs new file mode 100644 index 00000000..41c1c6c7 --- /dev/null +++ b/src/Adaptive.Cluster/Codecs/RecordingLogEncoder.cs @@ -0,0 +1,515 @@ +/* Generated SBE (Simple Binary Encoding) message codec */ +using System; +using System.Text; +using System.Collections.Generic; +using Adaptive.Agrona; + + +namespace Adaptive.Cluster.Codecs { + +public class RecordingLogEncoder +{ + public const ushort BLOCK_LENGTH = 20; + public const ushort TEMPLATE_ID = 64; + public const ushort SCHEMA_ID = 1; + public const ushort SCHEMA_VERSION = 1; + + private RecordingLogEncoder _parentMessage; + private IMutableDirectBuffer _buffer; + protected int _offset; + protected int _limit; + + public RecordingLogEncoder() + { + _parentMessage = this; + } + + public ushort SbeBlockLength() + { + return BLOCK_LENGTH; + } + + public ushort SbeTemplateId() + { + return TEMPLATE_ID; + } + + public ushort SbeSchemaId() + { + return SCHEMA_ID; + } + + public ushort SbeSchemaVersion() + { + return SCHEMA_VERSION; + } + + public string SbeSemanticType() + { + return ""; + } + + public IMutableDirectBuffer Buffer() + { + return _buffer; + } + + public int Offset() + { + return _offset; + } + + public RecordingLogEncoder Wrap(IMutableDirectBuffer buffer, int offset) + { + this._buffer = buffer; + this._offset = offset; + Limit(offset + BLOCK_LENGTH); + + return this; + } + + public RecordingLogEncoder WrapAndApplyHeader( + IMutableDirectBuffer buffer, int offset, MessageHeaderEncoder headerEncoder) + { + headerEncoder + .Wrap(buffer, offset) + .BlockLength(BLOCK_LENGTH) + .TemplateId(TEMPLATE_ID) + .SchemaId(SCHEMA_ID) + .Version(SCHEMA_VERSION); + + return Wrap(buffer, offset + MessageHeaderEncoder.ENCODED_LENGTH); + } + + public int EncodedLength() + { + return _limit - _offset; + } + + public int Limit() + { + return _limit; + } + + public void Limit(int limit) + { + this._limit = limit; + } + + public static int CorrelationIdEncodingOffset() + { + return 0; + } + + public static int CorrelationIdEncodingLength() + { + return 8; + } + + public static long CorrelationIdNullValue() + { + return -9223372036854775808L; + } + + public static long CorrelationIdMinValue() + { + return -9223372036854775807L; + } + + public static long CorrelationIdMaxValue() + { + return 9223372036854775807L; + } + + public RecordingLogEncoder CorrelationId(long value) + { + _buffer.PutLong(_offset + 0, value, ByteOrder.LittleEndian); + return this; + } + + + public static int RequestMemberIdEncodingOffset() + { + return 8; + } + + public static int RequestMemberIdEncodingLength() + { + return 4; + } + + public static int RequestMemberIdNullValue() + { + return -2147483648; + } + + public static int RequestMemberIdMinValue() + { + return -2147483647; + } + + public static int RequestMemberIdMaxValue() + { + return 2147483647; + } + + public RecordingLogEncoder RequestMemberId(int value) + { + _buffer.PutInt(_offset + 8, value, ByteOrder.LittleEndian); + return this; + } + + + public static int LeaderMemberIdEncodingOffset() + { + return 12; + } + + public static int LeaderMemberIdEncodingLength() + { + return 4; + } + + public static int LeaderMemberIdNullValue() + { + return -2147483648; + } + + public static int LeaderMemberIdMinValue() + { + return -2147483647; + } + + public static int LeaderMemberIdMaxValue() + { + return 2147483647; + } + + public RecordingLogEncoder LeaderMemberId(int value) + { + _buffer.PutInt(_offset + 12, value, ByteOrder.LittleEndian); + return this; + } + + + private EntriesEncoder _Entries = new EntriesEncoder(); + + public static long EntriesId() + { + return 4; + } + + public EntriesEncoder EntriesCount(int count) + { + _Entries.Wrap(_parentMessage, _buffer, count); + return _Entries; + } + + public class EntriesEncoder + { + private static int HEADER_SIZE = 4; + private GroupSizeEncodingEncoder _dimensions = new GroupSizeEncodingEncoder(); + private RecordingLogEncoder _parentMessage; + private IMutableDirectBuffer _buffer; + private int _count; + private int _index; + private int _offset; + + public void Wrap( + RecordingLogEncoder parentMessage, IMutableDirectBuffer buffer, int count) + { + if (count < 0 || count > 65534) + { + throw new ArgumentException("count outside allowed range: count=" + count); + } + + this._parentMessage = parentMessage; + this._buffer = buffer; + _dimensions.Wrap(buffer, parentMessage.Limit()); + _dimensions.BlockLength((ushort)64); + _dimensions.NumInGroup((ushort)count); + _index = -1; + this._count = count; + parentMessage.Limit(parentMessage.Limit() + HEADER_SIZE); + } + + public static int SbeHeaderSize() + { + return HEADER_SIZE; + } + + public static int SbeBlockLength() + { + return 64; + } + + public EntriesEncoder Next() + { + if (_index + 1 >= _count) + { + throw new IndexOutOfRangeException(); + } + + _offset = _parentMessage.Limit(); + _parentMessage.Limit(_offset + SbeBlockLength()); + ++_index; + + return this; + } + + public static int RecordingIdEncodingOffset() + { + return 0; + } + + public static int RecordingIdEncodingLength() + { + return 8; + } + + public static long RecordingIdNullValue() + { + return -9223372036854775808L; + } + + public static long RecordingIdMinValue() + { + return -9223372036854775807L; + } + + public static long RecordingIdMaxValue() + { + return 9223372036854775807L; + } + + public EntriesEncoder RecordingId(long value) + { + _buffer.PutLong(_offset + 0, value, ByteOrder.LittleEndian); + return this; + } + + + public static int LeadershipTermIdEncodingOffset() + { + return 8; + } + + public static int LeadershipTermIdEncodingLength() + { + return 8; + } + + public static long LeadershipTermIdNullValue() + { + return -9223372036854775808L; + } + + public static long LeadershipTermIdMinValue() + { + return -9223372036854775807L; + } + + public static long LeadershipTermIdMaxValue() + { + return 9223372036854775807L; + } + + public EntriesEncoder LeadershipTermId(long value) + { + _buffer.PutLong(_offset + 8, value, ByteOrder.LittleEndian); + return this; + } + + + public static int TermBaseLogPositionEncodingOffset() + { + return 16; + } + + public static int TermBaseLogPositionEncodingLength() + { + return 8; + } + + public static long TermBaseLogPositionNullValue() + { + return -9223372036854775808L; + } + + public static long TermBaseLogPositionMinValue() + { + return -9223372036854775807L; + } + + public static long TermBaseLogPositionMaxValue() + { + return 9223372036854775807L; + } + + public EntriesEncoder TermBaseLogPosition(long value) + { + _buffer.PutLong(_offset + 16, value, ByteOrder.LittleEndian); + return this; + } + + + public static int LogPositionEncodingOffset() + { + return 24; + } + + public static int LogPositionEncodingLength() + { + return 8; + } + + public static long LogPositionNullValue() + { + return -9223372036854775808L; + } + + public static long LogPositionMinValue() + { + return -9223372036854775807L; + } + + public static long LogPositionMaxValue() + { + return 9223372036854775807L; + } + + public EntriesEncoder LogPosition(long value) + { + _buffer.PutLong(_offset + 24, value, ByteOrder.LittleEndian); + return this; + } + + + public static int TimestampEncodingOffset() + { + return 32; + } + + public static int TimestampEncodingLength() + { + return 8; + } + + public static long TimestampNullValue() + { + return -9223372036854775808L; + } + + public static long TimestampMinValue() + { + return -9223372036854775807L; + } + + public static long TimestampMaxValue() + { + return 9223372036854775807L; + } + + public EntriesEncoder Timestamp(long value) + { + _buffer.PutLong(_offset + 32, value, ByteOrder.LittleEndian); + return this; + } + + + public static int ServiceIdEncodingOffset() + { + return 40; + } + + public static int ServiceIdEncodingLength() + { + return 4; + } + + public static int ServiceIdNullValue() + { + return -2147483648; + } + + public static int ServiceIdMinValue() + { + return -2147483647; + } + + public static int ServiceIdMaxValue() + { + return 2147483647; + } + + public EntriesEncoder ServiceId(int value) + { + _buffer.PutInt(_offset + 40, value, ByteOrder.LittleEndian); + return this; + } + + + public static int EntryTypeEncodingOffset() + { + return 44; + } + + public static int EntryTypeEncodingLength() + { + return 4; + } + + public static int EntryTypeNullValue() + { + return -2147483648; + } + + public static int EntryTypeMinValue() + { + return -2147483647; + } + + public static int EntryTypeMaxValue() + { + return 2147483647; + } + + public EntriesEncoder EntryType(int value) + { + _buffer.PutInt(_offset + 44, value, ByteOrder.LittleEndian); + return this; + } + + + public static int IsCurrentEncodingOffset() + { + return 48; + } + + public static int IsCurrentEncodingLength() + { + return 4; + } + + public EntriesEncoder IsCurrent(BooleanType value) + { + _buffer.PutInt(_offset + 48, (int)value, ByteOrder.LittleEndian); + return this; + } + } + + + public override string ToString() + { + return AppendTo(new StringBuilder(100)).ToString(); + } + + public StringBuilder AppendTo(StringBuilder builder) + { + RecordingLogDecoder writer = new RecordingLogDecoder(); + writer.Wrap(_buffer, _offset, BLOCK_LENGTH, SCHEMA_VERSION); + + return writer.AppendTo(builder); + } +} +} diff --git a/src/Adaptive.Cluster/Codecs/QueryResponseDecoder.cs b/src/Adaptive.Cluster/Codecs/RecordingLogQueryDecoder.cs similarity index 56% rename from src/Adaptive.Cluster/Codecs/QueryResponseDecoder.cs rename to src/Adaptive.Cluster/Codecs/RecordingLogQueryDecoder.cs index 4eeb2359..e471b668 100644 --- a/src/Adaptive.Cluster/Codecs/QueryResponseDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/RecordingLogQueryDecoder.cs @@ -7,21 +7,21 @@ namespace Adaptive.Cluster.Codecs { -public class QueryResponseDecoder +public class RecordingLogQueryDecoder { - public const ushort BLOCK_LENGTH = 16; - public const ushort TEMPLATE_ID = 60; + public const ushort BLOCK_LENGTH = 32; + public const ushort TEMPLATE_ID = 63; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; - private QueryResponseDecoder _parentMessage; + private RecordingLogQueryDecoder _parentMessage; private IDirectBuffer _buffer; protected int _offset; protected int _limit; protected int _actingBlockLength; protected int _actingVersion; - public QueryResponseDecoder() + public RecordingLogQueryDecoder() { _parentMessage = this; } @@ -61,7 +61,7 @@ public int Offset() return _offset; } - public QueryResponseDecoder Wrap( + public RecordingLogQueryDecoder Wrap( IDirectBuffer buffer, int offset, int actingBlockLength, int actingVersion) { this._buffer = buffer; @@ -196,27 +196,27 @@ public int RequestMemberId() } - public static int ResponseMemberIdId() + public static int LeaderMemberIdId() { return 3; } - public static int ResponseMemberIdSinceVersion() + public static int LeaderMemberIdSinceVersion() { return 0; } - public static int ResponseMemberIdEncodingOffset() + public static int LeaderMemberIdEncodingOffset() { return 12; } - public static int ResponseMemberIdEncodingLength() + public static int LeaderMemberIdEncodingLength() { return 4; } - public static string ResponseMemberIdMetaAttribute(MetaAttribute metaAttribute) + public static string LeaderMemberIdMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -229,38 +229,48 @@ public static string ResponseMemberIdMetaAttribute(MetaAttribute metaAttribute) return ""; } - public static int ResponseMemberIdNullValue() + public static int LeaderMemberIdNullValue() { return -2147483648; } - public static int ResponseMemberIdMinValue() + public static int LeaderMemberIdMinValue() { return -2147483647; } - public static int ResponseMemberIdMaxValue() + public static int LeaderMemberIdMaxValue() { return 2147483647; } - public int ResponseMemberId() + public int LeaderMemberId() { return _buffer.GetInt(_offset + 12, ByteOrder.LittleEndian); } - public static int EncodedResponseId() + public static int FromLeadershipTermIdId() { return 4; } - public static int EncodedResponseSinceVersion() + public static int FromLeadershipTermIdSinceVersion() { return 0; } - public static string EncodedResponseMetaAttribute(MetaAttribute metaAttribute) + public static int FromLeadershipTermIdEncodingOffset() + { + return 16; + } + + public static int FromLeadershipTermIdEncodingLength() + { + return 8; + } + + public static string FromLeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -273,41 +283,120 @@ public static string EncodedResponseMetaAttribute(MetaAttribute metaAttribute) return ""; } - public static int EncodedResponseHeaderLength() + public static long FromLeadershipTermIdNullValue() + { + return -9223372036854775808L; + } + + public static long FromLeadershipTermIdMinValue() + { + return -9223372036854775807L; + } + + public static long FromLeadershipTermIdMaxValue() + { + return 9223372036854775807L; + } + + public long FromLeadershipTermId() + { + return _buffer.GetLong(_offset + 16, ByteOrder.LittleEndian); + } + + + public static int CountId() + { + return 5; + } + + public static int CountSinceVersion() + { + return 0; + } + + public static int CountEncodingOffset() + { + return 24; + } + + public static int CountEncodingLength() { return 4; } - public int EncodedResponseLength() + public static string CountMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static int CountNullValue() { - int limit = _parentMessage.Limit(); - return (int)unchecked((uint)_buffer.GetInt(limit, ByteOrder.LittleEndian)); + return -2147483648; } - public int GetEncodedResponse(IMutableDirectBuffer dst, int dstOffset, int length) + public static int CountMinValue() { - int headerLength = 4; - int limit = _parentMessage.Limit(); - int dataLength = (int)unchecked((uint)_buffer.GetInt(limit, ByteOrder.LittleEndian)); - int bytesCopied = Math.Min(length, dataLength); - _parentMessage.Limit(limit + headerLength + dataLength); - _buffer.GetBytes(limit + headerLength, dst, dstOffset, bytesCopied); + return -2147483647; + } - return bytesCopied; + public static int CountMaxValue() + { + return 2147483647; } - public int GetEncodedResponse(byte[] dst, int dstOffset, int length) + public int Count() { - int headerLength = 4; - int limit = _parentMessage.Limit(); - int dataLength = (int)unchecked((uint)_buffer.GetInt(limit, ByteOrder.LittleEndian)); - int bytesCopied = Math.Min(length, dataLength); - _parentMessage.Limit(limit + headerLength + dataLength); - _buffer.GetBytes(limit + headerLength, dst, dstOffset, bytesCopied); + return _buffer.GetInt(_offset + 24, ByteOrder.LittleEndian); + } + - return bytesCopied; + public static int IncludeSnapshotsId() + { + return 6; + } + + public static int IncludeSnapshotsSinceVersion() + { + return 0; } + public static int IncludeSnapshotsEncodingOffset() + { + return 28; + } + + public static int IncludeSnapshotsEncodingLength() + { + return 4; + } + + public static string IncludeSnapshotsMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public BooleanType IncludeSnapshots() + { + return (BooleanType)_buffer.GetInt(_offset + 28, ByteOrder.LittleEndian); + } + + public override string ToString() { @@ -318,7 +407,7 @@ public StringBuilder AppendTo(StringBuilder builder) { int originalLimit = Limit(); Limit(_offset + _actingBlockLength); - builder.Append("[QueryResponse](sbeTemplateId="); + builder.Append("[RecordingLogQuery](sbeTemplateId="); builder.Append(TEMPLATE_ID); builder.Append("|sbeSchemaId="); builder.Append(SCHEMA_ID); @@ -347,14 +436,25 @@ public StringBuilder AppendTo(StringBuilder builder) builder.Append("RequestMemberId="); builder.Append(RequestMemberId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='responseMemberId', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=12, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='leaderMemberId', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=12, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=12, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("ResponseMemberId="); - builder.Append(ResponseMemberId()); + builder.Append("LeaderMemberId="); + builder.Append(LeaderMemberId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='fromLeadershipTermId', referencedName='null', description='null', id=4, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("FromLeadershipTermId="); + builder.Append(FromLeadershipTermId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='count', referencedName='null', description='null', id=5, version=0, deprecated=0, encodedLength=0, offset=24, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=24, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("Count="); + builder.Append(Count()); builder.Append('|'); - //Token{signal=BEGIN_VAR_DATA, name='encodedResponse', referencedName='null', description='null', id=4, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("EncodedResponse="); - builder.Append(EncodedResponseLength() + " raw bytes"); + //Token{signal=BEGIN_FIELD, name='includeSnapshots', referencedName='null', description='null', id=6, version=0, deprecated=0, encodedLength=0, offset=28, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_ENUM, name='BooleanType', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=28, componentTokenCount=4, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='null', timeUnit=null, semanticType='null'}} + builder.Append("IncludeSnapshots="); + builder.Append(IncludeSnapshots()); Limit(originalLimit); diff --git a/src/Adaptive.Cluster/Codecs/QueryResponseEncoder.cs b/src/Adaptive.Cluster/Codecs/RecordingLogQueryEncoder.cs similarity index 59% rename from src/Adaptive.Cluster/Codecs/QueryResponseEncoder.cs rename to src/Adaptive.Cluster/Codecs/RecordingLogQueryEncoder.cs index 49b7dd3e..86d9953e 100644 --- a/src/Adaptive.Cluster/Codecs/QueryResponseEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/RecordingLogQueryEncoder.cs @@ -7,19 +7,19 @@ namespace Adaptive.Cluster.Codecs { -public class QueryResponseEncoder +public class RecordingLogQueryEncoder { - public const ushort BLOCK_LENGTH = 16; - public const ushort TEMPLATE_ID = 60; + public const ushort BLOCK_LENGTH = 32; + public const ushort TEMPLATE_ID = 63; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; - private QueryResponseEncoder _parentMessage; + private RecordingLogQueryEncoder _parentMessage; private IMutableDirectBuffer _buffer; protected int _offset; protected int _limit; - public QueryResponseEncoder() + public RecordingLogQueryEncoder() { _parentMessage = this; } @@ -59,7 +59,7 @@ public int Offset() return _offset; } - public QueryResponseEncoder Wrap(IMutableDirectBuffer buffer, int offset) + public RecordingLogQueryEncoder Wrap(IMutableDirectBuffer buffer, int offset) { this._buffer = buffer; this._offset = offset; @@ -68,7 +68,7 @@ public QueryResponseEncoder Wrap(IMutableDirectBuffer buffer, int offset) return this; } - public QueryResponseEncoder WrapAndApplyHeader( + public RecordingLogQueryEncoder WrapAndApplyHeader( IMutableDirectBuffer buffer, int offset, MessageHeaderEncoder headerEncoder) { headerEncoder @@ -121,7 +121,7 @@ public static long CorrelationIdMaxValue() return 9223372036854775807L; } - public QueryResponseEncoder CorrelationId(long value) + public RecordingLogQueryEncoder CorrelationId(long value) { _buffer.PutLong(_offset + 0, value, ByteOrder.LittleEndian); return this; @@ -153,97 +153,122 @@ public static int RequestMemberIdMaxValue() return 2147483647; } - public QueryResponseEncoder RequestMemberId(int value) + public RecordingLogQueryEncoder RequestMemberId(int value) { _buffer.PutInt(_offset + 8, value, ByteOrder.LittleEndian); return this; } - public static int ResponseMemberIdEncodingOffset() + public static int LeaderMemberIdEncodingOffset() { return 12; } - public static int ResponseMemberIdEncodingLength() + public static int LeaderMemberIdEncodingLength() { return 4; } - public static int ResponseMemberIdNullValue() + public static int LeaderMemberIdNullValue() { return -2147483648; } - public static int ResponseMemberIdMinValue() + public static int LeaderMemberIdMinValue() { return -2147483647; } - public static int ResponseMemberIdMaxValue() + public static int LeaderMemberIdMaxValue() { return 2147483647; } - public QueryResponseEncoder ResponseMemberId(int value) + public RecordingLogQueryEncoder LeaderMemberId(int value) { _buffer.PutInt(_offset + 12, value, ByteOrder.LittleEndian); return this; } - public static int EncodedResponseId() + public static int FromLeadershipTermIdEncodingOffset() { - return 4; + return 16; } - public static string EncodedResponseMetaAttribute(MetaAttribute metaAttribute) + public static int FromLeadershipTermIdEncodingLength() { - switch (metaAttribute) - { - case MetaAttribute.EPOCH: return "unix"; - case MetaAttribute.TIME_UNIT: return "nanosecond"; - case MetaAttribute.SEMANTIC_TYPE: return ""; - case MetaAttribute.PRESENCE: return "required"; - } + return 8; + } - return ""; + public static long FromLeadershipTermIdNullValue() + { + return -9223372036854775808L; + } + + public static long FromLeadershipTermIdMinValue() + { + return -9223372036854775807L; + } + + public static long FromLeadershipTermIdMaxValue() + { + return 9223372036854775807L; + } + + public RecordingLogQueryEncoder FromLeadershipTermId(long value) + { + _buffer.PutLong(_offset + 16, value, ByteOrder.LittleEndian); + return this; + } + + + public static int CountEncodingOffset() + { + return 24; } - public static int EncodedResponseHeaderLength() + public static int CountEncodingLength() { return 4; } - public QueryResponseEncoder PutEncodedResponse(IDirectBuffer src, int srcOffset, int length) + public static int CountNullValue() { - if (length > 1073741824) - { - throw new InvalidOperationException("length > maxValue for type: " + length); - } + return -2147483648; + } - int headerLength = 4; - int limit = _parentMessage.Limit(); - _parentMessage.Limit(limit + headerLength + length); - _buffer.PutInt(limit, unchecked((int)length), ByteOrder.LittleEndian); - _buffer.PutBytes(limit + headerLength, src, srcOffset, length); + public static int CountMinValue() + { + return -2147483647; + } + public static int CountMaxValue() + { + return 2147483647; + } + + public RecordingLogQueryEncoder Count(int value) + { + _buffer.PutInt(_offset + 24, value, ByteOrder.LittleEndian); return this; } - public QueryResponseEncoder PutEncodedResponse(byte[] src, int srcOffset, int length) + + public static int IncludeSnapshotsEncodingOffset() { - if (length > 1073741824) - { - throw new InvalidOperationException("length > maxValue for type: " + length); - } + return 28; + } - int headerLength = 4; - int limit = _parentMessage.Limit(); - _parentMessage.Limit(limit + headerLength + length); - _buffer.PutInt(limit, unchecked((int)length), ByteOrder.LittleEndian); - _buffer.PutBytes(limit + headerLength, src, srcOffset, length); + public static int IncludeSnapshotsEncodingLength() + { + return 4; + } + public RecordingLogQueryEncoder IncludeSnapshots(BooleanType value) + { + _buffer.PutInt(_offset + 28, (int)value, ByteOrder.LittleEndian); return this; } @@ -255,7 +280,7 @@ public override string ToString() public StringBuilder AppendTo(StringBuilder builder) { - QueryResponseDecoder writer = new QueryResponseDecoder(); + RecordingLogQueryDecoder writer = new RecordingLogQueryDecoder(); writer.Wrap(_buffer, _offset, BLOCK_LENGTH, SCHEMA_VERSION); return writer.AppendTo(builder); diff --git a/src/Adaptive.Cluster/Codecs/RecoveryPlanDecoder.cs b/src/Adaptive.Cluster/Codecs/RecoveryPlanDecoder.cs index 68d64437..f722fc17 100644 --- a/src/Adaptive.Cluster/Codecs/RecoveryPlanDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/RecoveryPlanDecoder.cs @@ -9,8 +9,8 @@ namespace Adaptive.Cluster.Codecs { public class RecoveryPlanDecoder { - public const ushort BLOCK_LENGTH = 32; - public const ushort TEMPLATE_ID = 110; + public const ushort BLOCK_LENGTH = 48; + public const ushort TEMPLATE_ID = 62; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; @@ -88,11 +88,173 @@ public void Limit(int limit) this._limit = limit; } - public static int LastLeadershipTermIdId() + public static int CorrelationIdId() { return 1; } + public static int CorrelationIdSinceVersion() + { + return 0; + } + + public static int CorrelationIdEncodingOffset() + { + return 0; + } + + public static int CorrelationIdEncodingLength() + { + return 8; + } + + public static string CorrelationIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long CorrelationIdNullValue() + { + return -9223372036854775808L; + } + + public static long CorrelationIdMinValue() + { + return -9223372036854775807L; + } + + public static long CorrelationIdMaxValue() + { + return 9223372036854775807L; + } + + public long CorrelationId() + { + return _buffer.GetLong(_offset + 0, ByteOrder.LittleEndian); + } + + + public static int RequestMemberIdId() + { + return 2; + } + + public static int RequestMemberIdSinceVersion() + { + return 0; + } + + public static int RequestMemberIdEncodingOffset() + { + return 8; + } + + public static int RequestMemberIdEncodingLength() + { + return 4; + } + + public static string RequestMemberIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static int RequestMemberIdNullValue() + { + return -2147483648; + } + + public static int RequestMemberIdMinValue() + { + return -2147483647; + } + + public static int RequestMemberIdMaxValue() + { + return 2147483647; + } + + public int RequestMemberId() + { + return _buffer.GetInt(_offset + 8, ByteOrder.LittleEndian); + } + + + public static int LeaderMemberIdId() + { + return 3; + } + + public static int LeaderMemberIdSinceVersion() + { + return 0; + } + + public static int LeaderMemberIdEncodingOffset() + { + return 12; + } + + public static int LeaderMemberIdEncodingLength() + { + return 4; + } + + public static string LeaderMemberIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static int LeaderMemberIdNullValue() + { + return -2147483648; + } + + public static int LeaderMemberIdMinValue() + { + return -2147483647; + } + + public static int LeaderMemberIdMaxValue() + { + return 2147483647; + } + + public int LeaderMemberId() + { + return _buffer.GetInt(_offset + 12, ByteOrder.LittleEndian); + } + + + public static int LastLeadershipTermIdId() + { + return 4; + } + public static int LastLeadershipTermIdSinceVersion() { return 0; @@ -100,7 +262,7 @@ public static int LastLeadershipTermIdSinceVersion() public static int LastLeadershipTermIdEncodingOffset() { - return 0; + return 16; } public static int LastLeadershipTermIdEncodingLength() @@ -138,13 +300,13 @@ public static long LastLeadershipTermIdMaxValue() public long LastLeadershipTermId() { - return _buffer.GetLong(_offset + 0, ByteOrder.LittleEndian); + return _buffer.GetLong(_offset + 16, ByteOrder.LittleEndian); } public static int LastTermBaseLogPositionId() { - return 2; + return 5; } public static int LastTermBaseLogPositionSinceVersion() @@ -154,7 +316,7 @@ public static int LastTermBaseLogPositionSinceVersion() public static int LastTermBaseLogPositionEncodingOffset() { - return 8; + return 24; } public static int LastTermBaseLogPositionEncodingLength() @@ -192,31 +354,85 @@ public static long LastTermBaseLogPositionMaxValue() public long LastTermBaseLogPosition() { - return _buffer.GetLong(_offset + 8, ByteOrder.LittleEndian); + return _buffer.GetLong(_offset + 24, ByteOrder.LittleEndian); } - public static int LastTermPositionCommittedId() + public static int AppendedLogPositionId() { - return 3; + return 6; } - public static int LastTermPositionCommittedSinceVersion() + public static int AppendedLogPositionSinceVersion() { return 0; } - public static int LastTermPositionCommittedEncodingOffset() + public static int AppendedLogPositionEncodingOffset() { - return 16; + return 32; + } + + public static int AppendedLogPositionEncodingLength() + { + return 8; + } + + public static string AppendedLogPositionMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long AppendedLogPositionNullValue() + { + return -9223372036854775808L; + } + + public static long AppendedLogPositionMinValue() + { + return -9223372036854775807L; + } + + public static long AppendedLogPositionMaxValue() + { + return 9223372036854775807L; + } + + public long AppendedLogPosition() + { + return _buffer.GetLong(_offset + 32, ByteOrder.LittleEndian); + } + + + public static int CommittedLogPositionId() + { + return 7; + } + + public static int CommittedLogPositionSinceVersion() + { + return 0; + } + + public static int CommittedLogPositionEncodingOffset() + { + return 40; } - public static int LastTermPositionCommittedEncodingLength() + public static int CommittedLogPositionEncodingLength() { return 8; } - public static string LastTermPositionCommittedMetaAttribute(MetaAttribute metaAttribute) + public static string CommittedLogPositionMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -229,100 +445,493 @@ public static string LastTermPositionCommittedMetaAttribute(MetaAttribute metaAt return ""; } - public static long LastTermPositionCommittedNullValue() + public static long CommittedLogPositionNullValue() { return -9223372036854775808L; } - public static long LastTermPositionCommittedMinValue() + public static long CommittedLogPositionMinValue() { return -9223372036854775807L; } - public static long LastTermPositionCommittedMaxValue() - { - return 9223372036854775807L; - } + public static long CommittedLogPositionMaxValue() + { + return 9223372036854775807L; + } + + public long CommittedLogPosition() + { + return _buffer.GetLong(_offset + 40, ByteOrder.LittleEndian); + } + + + private SnapshotsDecoder _Snapshots = new SnapshotsDecoder(); + + public static long SnapshotsDecoderId() + { + return 8; + } + + public static int SnapshotsDecoderSinceVersion() + { + return 0; + } + + public SnapshotsDecoder Snapshots() + { + _Snapshots.Wrap(_parentMessage, _buffer); + return _Snapshots; + } + + public class SnapshotsDecoder + { + private static int HEADER_SIZE = 4; + private GroupSizeEncodingDecoder _dimensions = new GroupSizeEncodingDecoder(); + private RecoveryPlanDecoder _parentMessage; + private IDirectBuffer _buffer; + private int _count; + private int _index; + private int _offset; + private int _blockLength; + + public void Wrap( + RecoveryPlanDecoder parentMessage, IDirectBuffer buffer) + { + this._parentMessage = parentMessage; + this._buffer = buffer; + _dimensions.Wrap(buffer, parentMessage.Limit()); + _blockLength = _dimensions.BlockLength(); + _count = _dimensions.NumInGroup(); + _index = -1; + parentMessage.Limit(parentMessage.Limit() + HEADER_SIZE); + } + + public static int SbeHeaderSize() + { + return HEADER_SIZE; + } + + public static int SbeBlockLength() + { + return 44; + } + + public int ActingBlockLength() + { + return _blockLength; + } + + public int Count() + { + return _count; + } + + public bool HasNext() + { + return (_index + 1) < _count; + } + + public SnapshotsDecoder Next() + { + if (_index + 1 >= _count) + { + throw new IndexOutOfRangeException(); + } + + _offset = _parentMessage.Limit(); + _parentMessage.Limit(_offset + _blockLength); + ++_index; + + return this; + } + + public static int RecordingIdId() + { + return 9; + } + + public static int RecordingIdSinceVersion() + { + return 0; + } + + public static int RecordingIdEncodingOffset() + { + return 0; + } + + public static int RecordingIdEncodingLength() + { + return 8; + } + + public static string RecordingIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long RecordingIdNullValue() + { + return -9223372036854775808L; + } + + public static long RecordingIdMinValue() + { + return -9223372036854775807L; + } + + public static long RecordingIdMaxValue() + { + return 9223372036854775807L; + } + + public long RecordingId() + { + return _buffer.GetLong(_offset + 0, ByteOrder.LittleEndian); + } + + + public static int LeadershipTermIdId() + { + return 10; + } + + public static int LeadershipTermIdSinceVersion() + { + return 0; + } + + public static int LeadershipTermIdEncodingOffset() + { + return 8; + } + + public static int LeadershipTermIdEncodingLength() + { + return 8; + } + + public static string LeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long LeadershipTermIdNullValue() + { + return -9223372036854775808L; + } + + public static long LeadershipTermIdMinValue() + { + return -9223372036854775807L; + } + + public static long LeadershipTermIdMaxValue() + { + return 9223372036854775807L; + } + + public long LeadershipTermId() + { + return _buffer.GetLong(_offset + 8, ByteOrder.LittleEndian); + } + + + public static int TermBaseLogPositionId() + { + return 11; + } + + public static int TermBaseLogPositionSinceVersion() + { + return 0; + } + + public static int TermBaseLogPositionEncodingOffset() + { + return 16; + } + + public static int TermBaseLogPositionEncodingLength() + { + return 8; + } + + public static string TermBaseLogPositionMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long TermBaseLogPositionNullValue() + { + return -9223372036854775808L; + } + + public static long TermBaseLogPositionMinValue() + { + return -9223372036854775807L; + } + + public static long TermBaseLogPositionMaxValue() + { + return 9223372036854775807L; + } + + public long TermBaseLogPosition() + { + return _buffer.GetLong(_offset + 16, ByteOrder.LittleEndian); + } + + + public static int LogPositionId() + { + return 12; + } + + public static int LogPositionSinceVersion() + { + return 0; + } + + public static int LogPositionEncodingOffset() + { + return 24; + } + + public static int LogPositionEncodingLength() + { + return 8; + } + + public static string LogPositionMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long LogPositionNullValue() + { + return -9223372036854775808L; + } + + public static long LogPositionMinValue() + { + return -9223372036854775807L; + } + + public static long LogPositionMaxValue() + { + return 9223372036854775807L; + } + + public long LogPosition() + { + return _buffer.GetLong(_offset + 24, ByteOrder.LittleEndian); + } + + + public static int TimestampId() + { + return 13; + } + + public static int TimestampSinceVersion() + { + return 0; + } + + public static int TimestampEncodingOffset() + { + return 32; + } + + public static int TimestampEncodingLength() + { + return 8; + } + + public static string TimestampMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long TimestampNullValue() + { + return -9223372036854775808L; + } + + public static long TimestampMinValue() + { + return -9223372036854775807L; + } + + public static long TimestampMaxValue() + { + return 9223372036854775807L; + } + + public long Timestamp() + { + return _buffer.GetLong(_offset + 32, ByteOrder.LittleEndian); + } + + + public static int ServiceIdId() + { + return 14; + } - public long LastTermPositionCommitted() - { - return _buffer.GetLong(_offset + 16, ByteOrder.LittleEndian); - } + public static int ServiceIdSinceVersion() + { + return 0; + } + public static int ServiceIdEncodingOffset() + { + return 40; + } - public static int LastTermPositionAppendedId() - { - return 4; - } + public static int ServiceIdEncodingLength() + { + return 4; + } - public static int LastTermPositionAppendedSinceVersion() - { - return 0; - } + public static string ServiceIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } - public static int LastTermPositionAppendedEncodingOffset() - { - return 24; - } + return ""; + } - public static int LastTermPositionAppendedEncodingLength() - { - return 8; - } + public static int ServiceIdNullValue() + { + return -2147483648; + } - public static string LastTermPositionAppendedMetaAttribute(MetaAttribute metaAttribute) - { - switch (metaAttribute) + public static int ServiceIdMinValue() { - case MetaAttribute.EPOCH: return "unix"; - case MetaAttribute.TIME_UNIT: return "nanosecond"; - case MetaAttribute.SEMANTIC_TYPE: return ""; - case MetaAttribute.PRESENCE: return "required"; + return -2147483647; } - return ""; - } + public static int ServiceIdMaxValue() + { + return 2147483647; + } - public static long LastTermPositionAppendedNullValue() - { - return -9223372036854775808L; - } + public int ServiceId() + { + return _buffer.GetInt(_offset + 40, ByteOrder.LittleEndian); + } - public static long LastTermPositionAppendedMinValue() - { - return -9223372036854775807L; - } - public static long LastTermPositionAppendedMaxValue() - { - return 9223372036854775807L; - } - public long LastTermPositionAppended() - { - return _buffer.GetLong(_offset + 24, ByteOrder.LittleEndian); - } + public override string ToString() + { + return AppendTo(new StringBuilder(100)).ToString(); + } + public StringBuilder AppendTo(StringBuilder builder) + { + builder.Append('('); + //Token{signal=BEGIN_FIELD, name='recordingId', referencedName='null', description='null', id=9, version=0, deprecated=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=0, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("RecordingId="); + builder.Append(RecordingId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='leadershipTermId', referencedName='null', description='null', id=10, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LeadershipTermId="); + builder.Append(LeadershipTermId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='termBaseLogPosition', referencedName='null', description='null', id=11, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("TermBaseLogPosition="); + builder.Append(TermBaseLogPosition()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='logPosition', referencedName='null', description='null', id=12, version=0, deprecated=0, encodedLength=0, offset=24, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=24, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LogPosition="); + builder.Append(LogPosition()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='timestamp', referencedName='null', description='null', id=13, version=0, deprecated=0, encodedLength=0, offset=32, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='time_t', referencedName='null', description='Epoch time in milliseconds since 1 Jan 1970 UTC', id=-1, version=0, deprecated=0, encodedLength=8, offset=32, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("Timestamp="); + builder.Append(Timestamp()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='serviceId', referencedName='null', description='null', id=14, version=0, deprecated=0, encodedLength=0, offset=40, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=40, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("ServiceId="); + builder.Append(ServiceId()); + builder.Append(')'); + return builder; + } + } - private StepsDecoder _Steps = new StepsDecoder(); + private LogsDecoder _Logs = new LogsDecoder(); - public static long StepsDecoderId() + public static long LogsDecoderId() { - return 5; + return 15; } - public static int StepsDecoderSinceVersion() + public static int LogsDecoderSinceVersion() { return 0; } - public StepsDecoder Steps() + public LogsDecoder Logs() { - _Steps.Wrap(_parentMessage, _buffer); - return _Steps; + _Logs.Wrap(_parentMessage, _buffer); + return _Logs; } - public class StepsDecoder + public class LogsDecoder { private static int HEADER_SIZE = 4; private GroupSizeEncodingDecoder _dimensions = new GroupSizeEncodingDecoder(); @@ -352,7 +961,7 @@ public static int SbeHeaderSize() public static int SbeBlockLength() { - return 72; + return 64; } public int ActingBlockLength() @@ -370,7 +979,7 @@ public bool HasNext() return (_index + 1) < _count; } - public StepsDecoder Next() + public LogsDecoder Next() { if (_index + 1 >= _count) { @@ -384,27 +993,27 @@ public StepsDecoder Next() return this; } - public static int RecordingStartPositionId() + public static int RecordingIdId() { - return 6; + return 16; } - public static int RecordingStartPositionSinceVersion() + public static int RecordingIdSinceVersion() { return 0; } - public static int RecordingStartPositionEncodingOffset() + public static int RecordingIdEncodingOffset() { return 0; } - public static int RecordingStartPositionEncodingLength() + public static int RecordingIdEncodingLength() { return 8; } - public static string RecordingStartPositionMetaAttribute(MetaAttribute metaAttribute) + public static string RecordingIdMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -417,48 +1026,48 @@ public static string RecordingStartPositionMetaAttribute(MetaAttribute metaAttri return ""; } - public static long RecordingStartPositionNullValue() + public static long RecordingIdNullValue() { return -9223372036854775808L; } - public static long RecordingStartPositionMinValue() + public static long RecordingIdMinValue() { return -9223372036854775807L; } - public static long RecordingStartPositionMaxValue() + public static long RecordingIdMaxValue() { return 9223372036854775807L; } - public long RecordingStartPosition() + public long RecordingId() { return _buffer.GetLong(_offset + 0, ByteOrder.LittleEndian); } - public static int RecordingStopPositionId() + public static int LeadershipTermIdId() { - return 7; + return 17; } - public static int RecordingStopPositionSinceVersion() + public static int LeadershipTermIdSinceVersion() { return 0; } - public static int RecordingStopPositionEncodingOffset() + public static int LeadershipTermIdEncodingOffset() { return 8; } - public static int RecordingStopPositionEncodingLength() + public static int LeadershipTermIdEncodingLength() { return 8; } - public static string RecordingStopPositionMetaAttribute(MetaAttribute metaAttribute) + public static string LeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -471,48 +1080,48 @@ public static string RecordingStopPositionMetaAttribute(MetaAttribute metaAttrib return ""; } - public static long RecordingStopPositionNullValue() + public static long LeadershipTermIdNullValue() { return -9223372036854775808L; } - public static long RecordingStopPositionMinValue() + public static long LeadershipTermIdMinValue() { return -9223372036854775807L; } - public static long RecordingStopPositionMaxValue() + public static long LeadershipTermIdMaxValue() { return 9223372036854775807L; } - public long RecordingStopPosition() + public long LeadershipTermId() { return _buffer.GetLong(_offset + 8, ByteOrder.LittleEndian); } - public static int RecordingIdId() + public static int TermBaseLogPositionId() { - return 8; + return 18; } - public static int RecordingIdSinceVersion() + public static int TermBaseLogPositionSinceVersion() { return 0; } - public static int RecordingIdEncodingOffset() + public static int TermBaseLogPositionEncodingOffset() { return 16; } - public static int RecordingIdEncodingLength() + public static int TermBaseLogPositionEncodingLength() { return 8; } - public static string RecordingIdMetaAttribute(MetaAttribute metaAttribute) + public static string TermBaseLogPositionMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -525,48 +1134,48 @@ public static string RecordingIdMetaAttribute(MetaAttribute metaAttribute) return ""; } - public static long RecordingIdNullValue() + public static long TermBaseLogPositionNullValue() { return -9223372036854775808L; } - public static long RecordingIdMinValue() + public static long TermBaseLogPositionMinValue() { return -9223372036854775807L; } - public static long RecordingIdMaxValue() + public static long TermBaseLogPositionMaxValue() { return 9223372036854775807L; } - public long RecordingId() + public long TermBaseLogPosition() { return _buffer.GetLong(_offset + 16, ByteOrder.LittleEndian); } - public static int LeadershipTermIdId() + public static int LogPositionId() { - return 9; + return 19; } - public static int LeadershipTermIdSinceVersion() + public static int LogPositionSinceVersion() { return 0; } - public static int LeadershipTermIdEncodingOffset() + public static int LogPositionEncodingOffset() { return 24; } - public static int LeadershipTermIdEncodingLength() + public static int LogPositionEncodingLength() { return 8; } - public static string LeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) + public static string LogPositionMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -579,48 +1188,48 @@ public static string LeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) return ""; } - public static long LeadershipTermIdNullValue() + public static long LogPositionNullValue() { return -9223372036854775808L; } - public static long LeadershipTermIdMinValue() + public static long LogPositionMinValue() { return -9223372036854775807L; } - public static long LeadershipTermIdMaxValue() + public static long LogPositionMaxValue() { return 9223372036854775807L; } - public long LeadershipTermId() + public long LogPosition() { return _buffer.GetLong(_offset + 24, ByteOrder.LittleEndian); } - public static int TermBaseLogPositionId() + public static int StartPositionId() { - return 10; + return 12; } - public static int TermBaseLogPositionSinceVersion() + public static int StartPositionSinceVersion() { return 0; } - public static int TermBaseLogPositionEncodingOffset() + public static int StartPositionEncodingOffset() { return 32; } - public static int TermBaseLogPositionEncodingLength() + public static int StartPositionEncodingLength() { return 8; } - public static string TermBaseLogPositionMetaAttribute(MetaAttribute metaAttribute) + public static string StartPositionMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -633,48 +1242,48 @@ public static string TermBaseLogPositionMetaAttribute(MetaAttribute metaAttribut return ""; } - public static long TermBaseLogPositionNullValue() + public static long StartPositionNullValue() { return -9223372036854775808L; } - public static long TermBaseLogPositionMinValue() + public static long StartPositionMinValue() { return -9223372036854775807L; } - public static long TermBaseLogPositionMaxValue() + public static long StartPositionMaxValue() { return 9223372036854775807L; } - public long TermBaseLogPosition() + public long StartPosition() { return _buffer.GetLong(_offset + 32, ByteOrder.LittleEndian); } - public static int TermPositionId() + public static int StopPositionId() { - return 11; + return 21; } - public static int TermPositionSinceVersion() + public static int StopPositionSinceVersion() { return 0; } - public static int TermPositionEncodingOffset() + public static int StopPositionEncodingOffset() { return 40; } - public static int TermPositionEncodingLength() + public static int StopPositionEncodingLength() { return 8; } - public static string TermPositionMetaAttribute(MetaAttribute metaAttribute) + public static string StopPositionMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -687,102 +1296,48 @@ public static string TermPositionMetaAttribute(MetaAttribute metaAttribute) return ""; } - public static long TermPositionNullValue() + public static long StopPositionNullValue() { return -9223372036854775808L; } - public static long TermPositionMinValue() + public static long StopPositionMinValue() { return -9223372036854775807L; } - public static long TermPositionMaxValue() + public static long StopPositionMaxValue() { return 9223372036854775807L; } - public long TermPosition() + public long StopPosition() { return _buffer.GetLong(_offset + 40, ByteOrder.LittleEndian); } - public static int TimestampId() + public static int InitialTermIdId() { - return 12; + return 22; } - public static int TimestampSinceVersion() + public static int InitialTermIdSinceVersion() { return 0; } - public static int TimestampEncodingOffset() + public static int InitialTermIdEncodingOffset() { return 48; } - public static int TimestampEncodingLength() - { - return 8; - } - - public static string TimestampMetaAttribute(MetaAttribute metaAttribute) - { - switch (metaAttribute) - { - case MetaAttribute.EPOCH: return "unix"; - case MetaAttribute.TIME_UNIT: return "nanosecond"; - case MetaAttribute.SEMANTIC_TYPE: return ""; - case MetaAttribute.PRESENCE: return "required"; - } - - return ""; - } - - public static long TimestampNullValue() - { - return -9223372036854775808L; - } - - public static long TimestampMinValue() - { - return -9223372036854775807L; - } - - public static long TimestampMaxValue() - { - return 9223372036854775807L; - } - - public long Timestamp() - { - return _buffer.GetLong(_offset + 48, ByteOrder.LittleEndian); - } - - - public static int VotedForMemberIdId() - { - return 13; - } - - public static int VotedForMemberIdSinceVersion() - { - return 0; - } - - public static int VotedForMemberIdEncodingOffset() - { - return 56; - } - - public static int VotedForMemberIdEncodingLength() + public static int InitialTermIdEncodingLength() { return 4; } - public static string VotedForMemberIdMetaAttribute(MetaAttribute metaAttribute) + public static string InitialTermIdMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -795,48 +1350,48 @@ public static string VotedForMemberIdMetaAttribute(MetaAttribute metaAttribute) return ""; } - public static int VotedForMemberIdNullValue() + public static int InitialTermIdNullValue() { return -2147483648; } - public static int VotedForMemberIdMinValue() + public static int InitialTermIdMinValue() { return -2147483647; } - public static int VotedForMemberIdMaxValue() + public static int InitialTermIdMaxValue() { return 2147483647; } - public int VotedForMemberId() + public int InitialTermId() { - return _buffer.GetInt(_offset + 56, ByteOrder.LittleEndian); + return _buffer.GetInt(_offset + 48, ByteOrder.LittleEndian); } - public static int EntryTypeId() + public static int TermBufferLengthId() { - return 14; + return 23; } - public static int EntryTypeSinceVersion() + public static int TermBufferLengthSinceVersion() { return 0; } - public static int EntryTypeEncodingOffset() + public static int TermBufferLengthEncodingOffset() { - return 60; + return 52; } - public static int EntryTypeEncodingLength() + public static int TermBufferLengthEncodingLength() { return 4; } - public static string EntryTypeMetaAttribute(MetaAttribute metaAttribute) + public static string TermBufferLengthMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -849,48 +1404,48 @@ public static string EntryTypeMetaAttribute(MetaAttribute metaAttribute) return ""; } - public static int EntryTypeNullValue() + public static int TermBufferLengthNullValue() { return -2147483648; } - public static int EntryTypeMinValue() + public static int TermBufferLengthMinValue() { return -2147483647; } - public static int EntryTypeMaxValue() + public static int TermBufferLengthMaxValue() { return 2147483647; } - public int EntryType() + public int TermBufferLength() { - return _buffer.GetInt(_offset + 60, ByteOrder.LittleEndian); + return _buffer.GetInt(_offset + 52, ByteOrder.LittleEndian); } - public static int EntryIndexId() + public static int MtuLengthId() { - return 15; + return 24; } - public static int EntryIndexSinceVersion() + public static int MtuLengthSinceVersion() { return 0; } - public static int EntryIndexEncodingOffset() + public static int MtuLengthEncodingOffset() { - return 64; + return 56; } - public static int EntryIndexEncodingLength() + public static int MtuLengthEncodingLength() { return 4; } - public static string EntryIndexMetaAttribute(MetaAttribute metaAttribute) + public static string MtuLengthMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -903,48 +1458,48 @@ public static string EntryIndexMetaAttribute(MetaAttribute metaAttribute) return ""; } - public static int EntryIndexNullValue() + public static int MtuLengthNullValue() { return -2147483648; } - public static int EntryIndexMinValue() + public static int MtuLengthMinValue() { return -2147483647; } - public static int EntryIndexMaxValue() + public static int MtuLengthMaxValue() { return 2147483647; } - public int EntryIndex() + public int MtuLength() { - return _buffer.GetInt(_offset + 64, ByteOrder.LittleEndian); + return _buffer.GetInt(_offset + 56, ByteOrder.LittleEndian); } - public static int RecordingSessionIdId() + public static int SessionIdId() { - return 16; + return 25; } - public static int RecordingSessionIdSinceVersion() + public static int SessionIdSinceVersion() { return 0; } - public static int RecordingSessionIdEncodingOffset() + public static int SessionIdEncodingOffset() { - return 68; + return 60; } - public static int RecordingSessionIdEncodingLength() + public static int SessionIdEncodingLength() { return 4; } - public static string RecordingSessionIdMetaAttribute(MetaAttribute metaAttribute) + public static string SessionIdMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -957,24 +1512,24 @@ public static string RecordingSessionIdMetaAttribute(MetaAttribute metaAttribute return ""; } - public static int RecordingSessionIdNullValue() + public static int SessionIdNullValue() { return -2147483648; } - public static int RecordingSessionIdMinValue() + public static int SessionIdMinValue() { return -2147483647; } - public static int RecordingSessionIdMaxValue() + public static int SessionIdMaxValue() { return 2147483647; } - public int RecordingSessionId() + public int SessionId() { - return _buffer.GetInt(_offset + 68, ByteOrder.LittleEndian); + return _buffer.GetInt(_offset + 60, ByteOrder.LittleEndian); } @@ -987,60 +1542,55 @@ public override string ToString() public StringBuilder AppendTo(StringBuilder builder) { builder.Append('('); - //Token{signal=BEGIN_FIELD, name='recordingStartPosition', referencedName='null', description='null', id=6, version=0, deprecated=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='recordingId', referencedName='null', description='null', id=16, version=0, deprecated=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=0, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("RecordingStartPosition="); - builder.Append(RecordingStartPosition()); - builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='recordingStopPosition', referencedName='null', description='null', id=7, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("RecordingStopPosition="); - builder.Append(RecordingStopPosition()); - builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='recordingId', referencedName='null', description='null', id=8, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("RecordingId="); builder.Append(RecordingId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='leadershipTermId', referencedName='null', description='null', id=9, version=0, deprecated=0, encodedLength=0, offset=24, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=24, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='leadershipTermId', referencedName='null', description='null', id=17, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("LeadershipTermId="); builder.Append(LeadershipTermId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='termBaseLogPosition', referencedName='null', description='null', id=10, version=0, deprecated=0, encodedLength=0, offset=32, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=32, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='termBaseLogPosition', referencedName='null', description='null', id=18, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("TermBaseLogPosition="); builder.Append(TermBaseLogPosition()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='termPosition', referencedName='null', description='null', id=11, version=0, deprecated=0, encodedLength=0, offset=40, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='logPosition', referencedName='null', description='null', id=19, version=0, deprecated=0, encodedLength=0, offset=24, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=24, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LogPosition="); + builder.Append(LogPosition()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='startPosition', referencedName='null', description='null', id=12, version=0, deprecated=0, encodedLength=0, offset=32, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=32, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("StartPosition="); + builder.Append(StartPosition()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='stopPosition', referencedName='null', description='null', id=21, version=0, deprecated=0, encodedLength=0, offset=40, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=40, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("TermPosition="); - builder.Append(TermPosition()); + builder.Append("StopPosition="); + builder.Append(StopPosition()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='timestamp', referencedName='null', description='null', id=12, version=0, deprecated=0, encodedLength=0, offset=48, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='time_t', referencedName='null', description='Epoch time in milliseconds since 1 Jan 1970 UTC', id=-1, version=0, deprecated=0, encodedLength=8, offset=48, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("Timestamp="); - builder.Append(Timestamp()); + //Token{signal=BEGIN_FIELD, name='initialTermId', referencedName='null', description='null', id=22, version=0, deprecated=0, encodedLength=0, offset=48, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=48, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("InitialTermId="); + builder.Append(InitialTermId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='votedForMemberId', referencedName='null', description='null', id=13, version=0, deprecated=0, encodedLength=0, offset=56, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='termBufferLength', referencedName='null', description='null', id=23, version=0, deprecated=0, encodedLength=0, offset=52, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=52, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("TermBufferLength="); + builder.Append(TermBufferLength()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='mtuLength', referencedName='null', description='null', id=24, version=0, deprecated=0, encodedLength=0, offset=56, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=56, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("VotedForMemberId="); - builder.Append(VotedForMemberId()); + builder.Append("MtuLength="); + builder.Append(MtuLength()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='entryType', referencedName='null', description='null', id=14, version=0, deprecated=0, encodedLength=0, offset=60, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='sessionId', referencedName='null', description='null', id=25, version=0, deprecated=0, encodedLength=0, offset=60, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=60, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("EntryType="); - builder.Append(EntryType()); - builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='entryIndex', referencedName='null', description='null', id=15, version=0, deprecated=0, encodedLength=0, offset=64, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=64, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("EntryIndex="); - builder.Append(EntryIndex()); - builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='recordingSessionId', referencedName='null', description='null', id=16, version=0, deprecated=0, encodedLength=0, offset=68, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=68, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("RecordingSessionId="); - builder.Append(RecordingSessionId()); + builder.Append("SessionId="); + builder.Append(SessionId()); builder.Append(')'); return builder; } @@ -1075,34 +1625,63 @@ public StringBuilder AppendTo(StringBuilder builder) } builder.Append(BLOCK_LENGTH); builder.Append("):"); - //Token{signal=BEGIN_FIELD, name='lastLeadershipTermId', referencedName='null', description='null', id=1, version=0, deprecated=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='correlationId', referencedName='null', description='null', id=1, version=0, deprecated=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=0, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("CorrelationId="); + builder.Append(CorrelationId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='requestMemberId', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("RequestMemberId="); + builder.Append(RequestMemberId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='leaderMemberId', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=12, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=12, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LeaderMemberId="); + builder.Append(LeaderMemberId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='lastLeadershipTermId', referencedName='null', description='null', id=4, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("LastLeadershipTermId="); builder.Append(LastLeadershipTermId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='lastTermBaseLogPosition', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='lastTermBaseLogPosition', referencedName='null', description='null', id=5, version=0, deprecated=0, encodedLength=0, offset=24, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=24, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("LastTermBaseLogPosition="); builder.Append(LastTermBaseLogPosition()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='lastTermPositionCommitted', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("LastTermPositionCommitted="); - builder.Append(LastTermPositionCommitted()); + //Token{signal=BEGIN_FIELD, name='appendedLogPosition', referencedName='null', description='null', id=6, version=0, deprecated=0, encodedLength=0, offset=32, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=32, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("AppendedLogPosition="); + builder.Append(AppendedLogPosition()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='lastTermPositionAppended', referencedName='null', description='null', id=4, version=0, deprecated=0, encodedLength=0, offset=24, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=24, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("LastTermPositionAppended="); - builder.Append(LastTermPositionAppended()); + //Token{signal=BEGIN_FIELD, name='committedLogPosition', referencedName='null', description='null', id=7, version=0, deprecated=0, encodedLength=0, offset=40, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=40, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("CommittedLogPosition="); + builder.Append(CommittedLogPosition()); + builder.Append('|'); + //Token{signal=BEGIN_GROUP, name='snapshots', referencedName='null', description='null', id=8, version=0, deprecated=0, encodedLength=44, offset=48, componentTokenCount=24, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='null', timeUnit=null, semanticType='null'}} + builder.Append("Snapshots=["); + SnapshotsDecoder Snapshots = this.Snapshots(); + if (Snapshots.Count() > 0) + { + while (Snapshots.HasNext()) + { + Snapshots.Next().AppendTo(builder); + builder.Append(','); + } + builder.Length = builder.Length - 1; + } + builder.Append(']'); builder.Append('|'); - //Token{signal=BEGIN_GROUP, name='steps', referencedName='null', description='null', id=5, version=0, deprecated=0, encodedLength=72, offset=32, componentTokenCount=39, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='null', timeUnit=null, semanticType='null'}} - builder.Append("Steps=["); - StepsDecoder Steps = this.Steps(); - if (Steps.Count() > 0) + //Token{signal=BEGIN_GROUP, name='logs', referencedName='null', description='null', id=15, version=0, deprecated=0, encodedLength=64, offset=-1, componentTokenCount=36, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='null', timeUnit=null, semanticType='null'}} + builder.Append("Logs=["); + LogsDecoder Logs = this.Logs(); + if (Logs.Count() > 0) { - while (Steps.HasNext()) + while (Logs.HasNext()) { - Steps.Next().AppendTo(builder); + Logs.Next().AppendTo(builder); builder.Append(','); } builder.Length = builder.Length - 1; diff --git a/src/Adaptive.Cluster/Codecs/RecoveryPlanEncoder.cs b/src/Adaptive.Cluster/Codecs/RecoveryPlanEncoder.cs index 6b0b1d30..2e798a8c 100644 --- a/src/Adaptive.Cluster/Codecs/RecoveryPlanEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/RecoveryPlanEncoder.cs @@ -9,8 +9,8 @@ namespace Adaptive.Cluster.Codecs { public class RecoveryPlanEncoder { - public const ushort BLOCK_LENGTH = 32; - public const ushort TEMPLATE_ID = 110; + public const ushort BLOCK_LENGTH = 48; + public const ushort TEMPLATE_ID = 62; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; @@ -96,11 +96,107 @@ public void Limit(int limit) this._limit = limit; } - public static int LastLeadershipTermIdEncodingOffset() + public static int CorrelationIdEncodingOffset() { return 0; } + public static int CorrelationIdEncodingLength() + { + return 8; + } + + public static long CorrelationIdNullValue() + { + return -9223372036854775808L; + } + + public static long CorrelationIdMinValue() + { + return -9223372036854775807L; + } + + public static long CorrelationIdMaxValue() + { + return 9223372036854775807L; + } + + public RecoveryPlanEncoder CorrelationId(long value) + { + _buffer.PutLong(_offset + 0, value, ByteOrder.LittleEndian); + return this; + } + + + public static int RequestMemberIdEncodingOffset() + { + return 8; + } + + public static int RequestMemberIdEncodingLength() + { + return 4; + } + + public static int RequestMemberIdNullValue() + { + return -2147483648; + } + + public static int RequestMemberIdMinValue() + { + return -2147483647; + } + + public static int RequestMemberIdMaxValue() + { + return 2147483647; + } + + public RecoveryPlanEncoder RequestMemberId(int value) + { + _buffer.PutInt(_offset + 8, value, ByteOrder.LittleEndian); + return this; + } + + + public static int LeaderMemberIdEncodingOffset() + { + return 12; + } + + public static int LeaderMemberIdEncodingLength() + { + return 4; + } + + public static int LeaderMemberIdNullValue() + { + return -2147483648; + } + + public static int LeaderMemberIdMinValue() + { + return -2147483647; + } + + public static int LeaderMemberIdMaxValue() + { + return 2147483647; + } + + public RecoveryPlanEncoder LeaderMemberId(int value) + { + _buffer.PutInt(_offset + 12, value, ByteOrder.LittleEndian); + return this; + } + + + public static int LastLeadershipTermIdEncodingOffset() + { + return 16; + } + public static int LastLeadershipTermIdEncodingLength() { return 8; @@ -123,14 +219,14 @@ public static long LastLeadershipTermIdMaxValue() public RecoveryPlanEncoder LastLeadershipTermId(long value) { - _buffer.PutLong(_offset + 0, value, ByteOrder.LittleEndian); + _buffer.PutLong(_offset + 16, value, ByteOrder.LittleEndian); return this; } public static int LastTermBaseLogPositionEncodingOffset() { - return 8; + return 24; } public static int LastTermBaseLogPositionEncodingLength() @@ -155,89 +251,89 @@ public static long LastTermBaseLogPositionMaxValue() public RecoveryPlanEncoder LastTermBaseLogPosition(long value) { - _buffer.PutLong(_offset + 8, value, ByteOrder.LittleEndian); + _buffer.PutLong(_offset + 24, value, ByteOrder.LittleEndian); return this; } - public static int LastTermPositionCommittedEncodingOffset() + public static int AppendedLogPositionEncodingOffset() { - return 16; + return 32; } - public static int LastTermPositionCommittedEncodingLength() + public static int AppendedLogPositionEncodingLength() { return 8; } - public static long LastTermPositionCommittedNullValue() + public static long AppendedLogPositionNullValue() { return -9223372036854775808L; } - public static long LastTermPositionCommittedMinValue() + public static long AppendedLogPositionMinValue() { return -9223372036854775807L; } - public static long LastTermPositionCommittedMaxValue() + public static long AppendedLogPositionMaxValue() { return 9223372036854775807L; } - public RecoveryPlanEncoder LastTermPositionCommitted(long value) + public RecoveryPlanEncoder AppendedLogPosition(long value) { - _buffer.PutLong(_offset + 16, value, ByteOrder.LittleEndian); + _buffer.PutLong(_offset + 32, value, ByteOrder.LittleEndian); return this; } - public static int LastTermPositionAppendedEncodingOffset() + public static int CommittedLogPositionEncodingOffset() { - return 24; + return 40; } - public static int LastTermPositionAppendedEncodingLength() + public static int CommittedLogPositionEncodingLength() { return 8; } - public static long LastTermPositionAppendedNullValue() + public static long CommittedLogPositionNullValue() { return -9223372036854775808L; } - public static long LastTermPositionAppendedMinValue() + public static long CommittedLogPositionMinValue() { return -9223372036854775807L; } - public static long LastTermPositionAppendedMaxValue() + public static long CommittedLogPositionMaxValue() { return 9223372036854775807L; } - public RecoveryPlanEncoder LastTermPositionAppended(long value) + public RecoveryPlanEncoder CommittedLogPosition(long value) { - _buffer.PutLong(_offset + 24, value, ByteOrder.LittleEndian); + _buffer.PutLong(_offset + 40, value, ByteOrder.LittleEndian); return this; } - private StepsEncoder _Steps = new StepsEncoder(); + private SnapshotsEncoder _Snapshots = new SnapshotsEncoder(); - public static long StepsId() + public static long SnapshotsId() { - return 5; + return 8; } - public StepsEncoder StepsCount(int count) + public SnapshotsEncoder SnapshotsCount(int count) { - _Steps.Wrap(_parentMessage, _buffer, count); - return _Steps; + _Snapshots.Wrap(_parentMessage, _buffer, count); + return _Snapshots; } - public class StepsEncoder + public class SnapshotsEncoder { private static int HEADER_SIZE = 4; private GroupSizeEncodingEncoder _dimensions = new GroupSizeEncodingEncoder(); @@ -258,7 +354,7 @@ public void Wrap( this._parentMessage = parentMessage; this._buffer = buffer; _dimensions.Wrap(buffer, parentMessage.Limit()); - _dimensions.BlockLength((ushort)72); + _dimensions.BlockLength((ushort)44); _dimensions.NumInGroup((ushort)count); _index = -1; this._count = count; @@ -272,10 +368,10 @@ public static int SbeHeaderSize() public static int SbeBlockLength() { - return 72; + return 44; } - public StepsEncoder Next() + public SnapshotsEncoder Next() { if (_index + 1 >= _count) { @@ -289,75 +385,269 @@ public StepsEncoder Next() return this; } - public static int RecordingStartPositionEncodingOffset() + public static int RecordingIdEncodingOffset() { return 0; } - public static int RecordingStartPositionEncodingLength() + public static int RecordingIdEncodingLength() { return 8; } - public static long RecordingStartPositionNullValue() + public static long RecordingIdNullValue() { return -9223372036854775808L; } - public static long RecordingStartPositionMinValue() + public static long RecordingIdMinValue() { return -9223372036854775807L; } - public static long RecordingStartPositionMaxValue() + public static long RecordingIdMaxValue() { return 9223372036854775807L; } - public StepsEncoder RecordingStartPosition(long value) + public SnapshotsEncoder RecordingId(long value) { _buffer.PutLong(_offset + 0, value, ByteOrder.LittleEndian); return this; } - public static int RecordingStopPositionEncodingOffset() + public static int LeadershipTermIdEncodingOffset() { return 8; } - public static int RecordingStopPositionEncodingLength() + public static int LeadershipTermIdEncodingLength() { return 8; } - public static long RecordingStopPositionNullValue() + public static long LeadershipTermIdNullValue() { return -9223372036854775808L; } - public static long RecordingStopPositionMinValue() + public static long LeadershipTermIdMinValue() { return -9223372036854775807L; } - public static long RecordingStopPositionMaxValue() + public static long LeadershipTermIdMaxValue() { return 9223372036854775807L; } - public StepsEncoder RecordingStopPosition(long value) + public SnapshotsEncoder LeadershipTermId(long value) { _buffer.PutLong(_offset + 8, value, ByteOrder.LittleEndian); return this; } - public static int RecordingIdEncodingOffset() + public static int TermBaseLogPositionEncodingOffset() { return 16; } + public static int TermBaseLogPositionEncodingLength() + { + return 8; + } + + public static long TermBaseLogPositionNullValue() + { + return -9223372036854775808L; + } + + public static long TermBaseLogPositionMinValue() + { + return -9223372036854775807L; + } + + public static long TermBaseLogPositionMaxValue() + { + return 9223372036854775807L; + } + + public SnapshotsEncoder TermBaseLogPosition(long value) + { + _buffer.PutLong(_offset + 16, value, ByteOrder.LittleEndian); + return this; + } + + + public static int LogPositionEncodingOffset() + { + return 24; + } + + public static int LogPositionEncodingLength() + { + return 8; + } + + public static long LogPositionNullValue() + { + return -9223372036854775808L; + } + + public static long LogPositionMinValue() + { + return -9223372036854775807L; + } + + public static long LogPositionMaxValue() + { + return 9223372036854775807L; + } + + public SnapshotsEncoder LogPosition(long value) + { + _buffer.PutLong(_offset + 24, value, ByteOrder.LittleEndian); + return this; + } + + + public static int TimestampEncodingOffset() + { + return 32; + } + + public static int TimestampEncodingLength() + { + return 8; + } + + public static long TimestampNullValue() + { + return -9223372036854775808L; + } + + public static long TimestampMinValue() + { + return -9223372036854775807L; + } + + public static long TimestampMaxValue() + { + return 9223372036854775807L; + } + + public SnapshotsEncoder Timestamp(long value) + { + _buffer.PutLong(_offset + 32, value, ByteOrder.LittleEndian); + return this; + } + + + public static int ServiceIdEncodingOffset() + { + return 40; + } + + public static int ServiceIdEncodingLength() + { + return 4; + } + + public static int ServiceIdNullValue() + { + return -2147483648; + } + + public static int ServiceIdMinValue() + { + return -2147483647; + } + + public static int ServiceIdMaxValue() + { + return 2147483647; + } + + public SnapshotsEncoder ServiceId(int value) + { + _buffer.PutInt(_offset + 40, value, ByteOrder.LittleEndian); + return this; + } + + } + + private LogsEncoder _Logs = new LogsEncoder(); + + public static long LogsId() + { + return 15; + } + + public LogsEncoder LogsCount(int count) + { + _Logs.Wrap(_parentMessage, _buffer, count); + return _Logs; + } + + public class LogsEncoder + { + private static int HEADER_SIZE = 4; + private GroupSizeEncodingEncoder _dimensions = new GroupSizeEncodingEncoder(); + private RecoveryPlanEncoder _parentMessage; + private IMutableDirectBuffer _buffer; + private int _count; + private int _index; + private int _offset; + + public void Wrap( + RecoveryPlanEncoder parentMessage, IMutableDirectBuffer buffer, int count) + { + if (count < 0 || count > 65534) + { + throw new ArgumentException("count outside allowed range: count=" + count); + } + + this._parentMessage = parentMessage; + this._buffer = buffer; + _dimensions.Wrap(buffer, parentMessage.Limit()); + _dimensions.BlockLength((ushort)64); + _dimensions.NumInGroup((ushort)count); + _index = -1; + this._count = count; + parentMessage.Limit(parentMessage.Limit() + HEADER_SIZE); + } + + public static int SbeHeaderSize() + { + return HEADER_SIZE; + } + + public static int SbeBlockLength() + { + return 64; + } + + public LogsEncoder Next() + { + if (_index + 1 >= _count) + { + throw new IndexOutOfRangeException(); + } + + _offset = _parentMessage.Limit(); + _parentMessage.Limit(_offset + SbeBlockLength()); + ++_index; + + return this; + } + + public static int RecordingIdEncodingOffset() + { + return 0; + } + public static int RecordingIdEncodingLength() { return 8; @@ -378,16 +668,16 @@ public static long RecordingIdMaxValue() return 9223372036854775807L; } - public StepsEncoder RecordingId(long value) + public LogsEncoder RecordingId(long value) { - _buffer.PutLong(_offset + 16, value, ByteOrder.LittleEndian); + _buffer.PutLong(_offset + 0, value, ByteOrder.LittleEndian); return this; } public static int LeadershipTermIdEncodingOffset() { - return 24; + return 8; } public static int LeadershipTermIdEncodingLength() @@ -410,16 +700,16 @@ public static long LeadershipTermIdMaxValue() return 9223372036854775807L; } - public StepsEncoder LeadershipTermId(long value) + public LogsEncoder LeadershipTermId(long value) { - _buffer.PutLong(_offset + 24, value, ByteOrder.LittleEndian); + _buffer.PutLong(_offset + 8, value, ByteOrder.LittleEndian); return this; } public static int TermBaseLogPositionEncodingOffset() { - return 32; + return 16; } public static int TermBaseLogPositionEncodingLength() @@ -442,201 +732,233 @@ public static long TermBaseLogPositionMaxValue() return 9223372036854775807L; } - public StepsEncoder TermBaseLogPosition(long value) + public LogsEncoder TermBaseLogPosition(long value) { - _buffer.PutLong(_offset + 32, value, ByteOrder.LittleEndian); + _buffer.PutLong(_offset + 16, value, ByteOrder.LittleEndian); return this; } - public static int TermPositionEncodingOffset() + public static int LogPositionEncodingOffset() { - return 40; + return 24; } - public static int TermPositionEncodingLength() + public static int LogPositionEncodingLength() { return 8; } - public static long TermPositionNullValue() + public static long LogPositionNullValue() { return -9223372036854775808L; } - public static long TermPositionMinValue() + public static long LogPositionMinValue() { return -9223372036854775807L; } - public static long TermPositionMaxValue() + public static long LogPositionMaxValue() { return 9223372036854775807L; } - public StepsEncoder TermPosition(long value) + public LogsEncoder LogPosition(long value) { - _buffer.PutLong(_offset + 40, value, ByteOrder.LittleEndian); + _buffer.PutLong(_offset + 24, value, ByteOrder.LittleEndian); return this; } - public static int TimestampEncodingOffset() + public static int StartPositionEncodingOffset() { - return 48; + return 32; } - public static int TimestampEncodingLength() + public static int StartPositionEncodingLength() { return 8; } - public static long TimestampNullValue() + public static long StartPositionNullValue() { return -9223372036854775808L; } - public static long TimestampMinValue() + public static long StartPositionMinValue() { return -9223372036854775807L; } - public static long TimestampMaxValue() + public static long StartPositionMaxValue() { return 9223372036854775807L; } - public StepsEncoder Timestamp(long value) + public LogsEncoder StartPosition(long value) { - _buffer.PutLong(_offset + 48, value, ByteOrder.LittleEndian); + _buffer.PutLong(_offset + 32, value, ByteOrder.LittleEndian); return this; } - public static int VotedForMemberIdEncodingOffset() + public static int StopPositionEncodingOffset() { - return 56; + return 40; + } + + public static int StopPositionEncodingLength() + { + return 8; + } + + public static long StopPositionNullValue() + { + return -9223372036854775808L; + } + + public static long StopPositionMinValue() + { + return -9223372036854775807L; } - public static int VotedForMemberIdEncodingLength() + public static long StopPositionMaxValue() + { + return 9223372036854775807L; + } + + public LogsEncoder StopPosition(long value) + { + _buffer.PutLong(_offset + 40, value, ByteOrder.LittleEndian); + return this; + } + + + public static int InitialTermIdEncodingOffset() + { + return 48; + } + + public static int InitialTermIdEncodingLength() { return 4; } - public static int VotedForMemberIdNullValue() + public static int InitialTermIdNullValue() { return -2147483648; } - public static int VotedForMemberIdMinValue() + public static int InitialTermIdMinValue() { return -2147483647; } - public static int VotedForMemberIdMaxValue() + public static int InitialTermIdMaxValue() { return 2147483647; } - public StepsEncoder VotedForMemberId(int value) + public LogsEncoder InitialTermId(int value) { - _buffer.PutInt(_offset + 56, value, ByteOrder.LittleEndian); + _buffer.PutInt(_offset + 48, value, ByteOrder.LittleEndian); return this; } - public static int EntryTypeEncodingOffset() + public static int TermBufferLengthEncodingOffset() { - return 60; + return 52; } - public static int EntryTypeEncodingLength() + public static int TermBufferLengthEncodingLength() { return 4; } - public static int EntryTypeNullValue() + public static int TermBufferLengthNullValue() { return -2147483648; } - public static int EntryTypeMinValue() + public static int TermBufferLengthMinValue() { return -2147483647; } - public static int EntryTypeMaxValue() + public static int TermBufferLengthMaxValue() { return 2147483647; } - public StepsEncoder EntryType(int value) + public LogsEncoder TermBufferLength(int value) { - _buffer.PutInt(_offset + 60, value, ByteOrder.LittleEndian); + _buffer.PutInt(_offset + 52, value, ByteOrder.LittleEndian); return this; } - public static int EntryIndexEncodingOffset() + public static int MtuLengthEncodingOffset() { - return 64; + return 56; } - public static int EntryIndexEncodingLength() + public static int MtuLengthEncodingLength() { return 4; } - public static int EntryIndexNullValue() + public static int MtuLengthNullValue() { return -2147483648; } - public static int EntryIndexMinValue() + public static int MtuLengthMinValue() { return -2147483647; } - public static int EntryIndexMaxValue() + public static int MtuLengthMaxValue() { return 2147483647; } - public StepsEncoder EntryIndex(int value) + public LogsEncoder MtuLength(int value) { - _buffer.PutInt(_offset + 64, value, ByteOrder.LittleEndian); + _buffer.PutInt(_offset + 56, value, ByteOrder.LittleEndian); return this; } - public static int RecordingSessionIdEncodingOffset() + public static int SessionIdEncodingOffset() { - return 68; + return 60; } - public static int RecordingSessionIdEncodingLength() + public static int SessionIdEncodingLength() { return 4; } - public static int RecordingSessionIdNullValue() + public static int SessionIdNullValue() { return -2147483648; } - public static int RecordingSessionIdMinValue() + public static int SessionIdMinValue() { return -2147483647; } - public static int RecordingSessionIdMaxValue() + public static int SessionIdMaxValue() { return 2147483647; } - public StepsEncoder RecordingSessionId(int value) + public LogsEncoder SessionId(int value) { - _buffer.PutInt(_offset + 68, value, ByteOrder.LittleEndian); + _buffer.PutInt(_offset + 60, value, ByteOrder.LittleEndian); return this; } diff --git a/src/Adaptive.Cluster/Codecs/RecoveryPlanQueryDecoder.cs b/src/Adaptive.Cluster/Codecs/RecoveryPlanQueryDecoder.cs index 03afac16..5c7fc1a0 100644 --- a/src/Adaptive.Cluster/Codecs/RecoveryPlanQueryDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/RecoveryPlanQueryDecoder.cs @@ -142,27 +142,27 @@ public long CorrelationId() } - public static int LeaderMemberIdId() + public static int RequestMemberIdId() { return 2; } - public static int LeaderMemberIdSinceVersion() + public static int RequestMemberIdSinceVersion() { return 0; } - public static int LeaderMemberIdEncodingOffset() + public static int RequestMemberIdEncodingOffset() { return 8; } - public static int LeaderMemberIdEncodingLength() + public static int RequestMemberIdEncodingLength() { return 4; } - public static string LeaderMemberIdMetaAttribute(MetaAttribute metaAttribute) + public static string RequestMemberIdMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -175,48 +175,48 @@ public static string LeaderMemberIdMetaAttribute(MetaAttribute metaAttribute) return ""; } - public static int LeaderMemberIdNullValue() + public static int RequestMemberIdNullValue() { return -2147483648; } - public static int LeaderMemberIdMinValue() + public static int RequestMemberIdMinValue() { return -2147483647; } - public static int LeaderMemberIdMaxValue() + public static int RequestMemberIdMaxValue() { return 2147483647; } - public int LeaderMemberId() + public int RequestMemberId() { return _buffer.GetInt(_offset + 8, ByteOrder.LittleEndian); } - public static int RequestMemberIdId() + public static int LeaderMemberIdId() { return 3; } - public static int RequestMemberIdSinceVersion() + public static int LeaderMemberIdSinceVersion() { return 0; } - public static int RequestMemberIdEncodingOffset() + public static int LeaderMemberIdEncodingOffset() { return 12; } - public static int RequestMemberIdEncodingLength() + public static int LeaderMemberIdEncodingLength() { return 4; } - public static string RequestMemberIdMetaAttribute(MetaAttribute metaAttribute) + public static string LeaderMemberIdMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -229,22 +229,22 @@ public static string RequestMemberIdMetaAttribute(MetaAttribute metaAttribute) return ""; } - public static int RequestMemberIdNullValue() + public static int LeaderMemberIdNullValue() { return -2147483648; } - public static int RequestMemberIdMinValue() + public static int LeaderMemberIdMinValue() { return -2147483647; } - public static int RequestMemberIdMaxValue() + public static int LeaderMemberIdMaxValue() { return 2147483647; } - public int RequestMemberId() + public int LeaderMemberId() { return _buffer.GetInt(_offset + 12, ByteOrder.LittleEndian); } @@ -284,15 +284,15 @@ public StringBuilder AppendTo(StringBuilder builder) builder.Append("CorrelationId="); builder.Append(CorrelationId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='leaderMemberId', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='requestMemberId', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("LeaderMemberId="); - builder.Append(LeaderMemberId()); - builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='requestMemberId', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=12, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=12, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("RequestMemberId="); builder.Append(RequestMemberId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='leaderMemberId', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=12, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=12, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LeaderMemberId="); + builder.Append(LeaderMemberId()); Limit(originalLimit); diff --git a/src/Adaptive.Cluster/Codecs/RecoveryPlanQueryEncoder.cs b/src/Adaptive.Cluster/Codecs/RecoveryPlanQueryEncoder.cs index 3b3eea1a..7dab93d6 100644 --- a/src/Adaptive.Cluster/Codecs/RecoveryPlanQueryEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/RecoveryPlanQueryEncoder.cs @@ -128,64 +128,64 @@ public RecoveryPlanQueryEncoder CorrelationId(long value) } - public static int LeaderMemberIdEncodingOffset() + public static int RequestMemberIdEncodingOffset() { return 8; } - public static int LeaderMemberIdEncodingLength() + public static int RequestMemberIdEncodingLength() { return 4; } - public static int LeaderMemberIdNullValue() + public static int RequestMemberIdNullValue() { return -2147483648; } - public static int LeaderMemberIdMinValue() + public static int RequestMemberIdMinValue() { return -2147483647; } - public static int LeaderMemberIdMaxValue() + public static int RequestMemberIdMaxValue() { return 2147483647; } - public RecoveryPlanQueryEncoder LeaderMemberId(int value) + public RecoveryPlanQueryEncoder RequestMemberId(int value) { _buffer.PutInt(_offset + 8, value, ByteOrder.LittleEndian); return this; } - public static int RequestMemberIdEncodingOffset() + public static int LeaderMemberIdEncodingOffset() { return 12; } - public static int RequestMemberIdEncodingLength() + public static int LeaderMemberIdEncodingLength() { return 4; } - public static int RequestMemberIdNullValue() + public static int LeaderMemberIdNullValue() { return -2147483648; } - public static int RequestMemberIdMinValue() + public static int LeaderMemberIdMinValue() { return -2147483647; } - public static int RequestMemberIdMaxValue() + public static int LeaderMemberIdMaxValue() { return 2147483647; } - public RecoveryPlanQueryEncoder RequestMemberId(int value) + public RecoveryPlanQueryEncoder LeaderMemberId(int value) { _buffer.PutInt(_offset + 12, value, ByteOrder.LittleEndian); return this; diff --git a/src/Adaptive.Cluster/Codecs/RequestVoteDecoder.cs b/src/Adaptive.Cluster/Codecs/RequestVoteDecoder.cs index dcba4c59..a4975f05 100644 --- a/src/Adaptive.Cluster/Codecs/RequestVoteDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/RequestVoteDecoder.cs @@ -9,7 +9,7 @@ namespace Adaptive.Cluster.Codecs { public class RequestVoteDecoder { - public const ushort BLOCK_LENGTH = 20; + public const ushort BLOCK_LENGTH = 28; public const ushort TEMPLATE_ID = 51; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; @@ -88,11 +88,65 @@ public void Limit(int limit) this._limit = limit; } - public static int LogPositionId() + public static int LogLeadershipTermIdId() { return 1; } + public static int LogLeadershipTermIdSinceVersion() + { + return 0; + } + + public static int LogLeadershipTermIdEncodingOffset() + { + return 0; + } + + public static int LogLeadershipTermIdEncodingLength() + { + return 8; + } + + public static string LogLeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long LogLeadershipTermIdNullValue() + { + return -9223372036854775808L; + } + + public static long LogLeadershipTermIdMinValue() + { + return -9223372036854775807L; + } + + public static long LogLeadershipTermIdMaxValue() + { + return 9223372036854775807L; + } + + public long LogLeadershipTermId() + { + return _buffer.GetLong(_offset + 0, ByteOrder.LittleEndian); + } + + + public static int LogPositionId() + { + return 2; + } + public static int LogPositionSinceVersion() { return 0; @@ -100,7 +154,7 @@ public static int LogPositionSinceVersion() public static int LogPositionEncodingOffset() { - return 0; + return 8; } public static int LogPositionEncodingLength() @@ -138,13 +192,13 @@ public static long LogPositionMaxValue() public long LogPosition() { - return _buffer.GetLong(_offset + 0, ByteOrder.LittleEndian); + return _buffer.GetLong(_offset + 8, ByteOrder.LittleEndian); } public static int CandidateTermIdId() { - return 2; + return 3; } public static int CandidateTermIdSinceVersion() @@ -154,7 +208,7 @@ public static int CandidateTermIdSinceVersion() public static int CandidateTermIdEncodingOffset() { - return 8; + return 16; } public static int CandidateTermIdEncodingLength() @@ -192,13 +246,13 @@ public static long CandidateTermIdMaxValue() public long CandidateTermId() { - return _buffer.GetLong(_offset + 8, ByteOrder.LittleEndian); + return _buffer.GetLong(_offset + 16, ByteOrder.LittleEndian); } public static int CandidateMemberIdId() { - return 3; + return 4; } public static int CandidateMemberIdSinceVersion() @@ -208,7 +262,7 @@ public static int CandidateMemberIdSinceVersion() public static int CandidateMemberIdEncodingOffset() { - return 16; + return 24; } public static int CandidateMemberIdEncodingLength() @@ -246,7 +300,7 @@ public static int CandidateMemberIdMaxValue() public int CandidateMemberId() { - return _buffer.GetInt(_offset + 16, ByteOrder.LittleEndian); + return _buffer.GetInt(_offset + 24, ByteOrder.LittleEndian); } @@ -279,18 +333,23 @@ public StringBuilder AppendTo(StringBuilder builder) } builder.Append(BLOCK_LENGTH); builder.Append("):"); - //Token{signal=BEGIN_FIELD, name='logPosition', referencedName='null', description='null', id=1, version=0, deprecated=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='logLeadershipTermId', referencedName='null', description='null', id=1, version=0, deprecated=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=0, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LogLeadershipTermId="); + builder.Append(LogLeadershipTermId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='logPosition', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("LogPosition="); builder.Append(LogPosition()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='candidateTermId', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='candidateTermId', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("CandidateTermId="); builder.Append(CandidateTermId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='candidateMemberId', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='candidateMemberId', referencedName='null', description='null', id=4, version=0, deprecated=0, encodedLength=0, offset=24, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=24, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("CandidateMemberId="); builder.Append(CandidateMemberId()); diff --git a/src/Adaptive.Cluster/Codecs/RequestVoteEncoder.cs b/src/Adaptive.Cluster/Codecs/RequestVoteEncoder.cs index e9e584f6..61437c72 100644 --- a/src/Adaptive.Cluster/Codecs/RequestVoteEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/RequestVoteEncoder.cs @@ -9,7 +9,7 @@ namespace Adaptive.Cluster.Codecs { public class RequestVoteEncoder { - public const ushort BLOCK_LENGTH = 20; + public const ushort BLOCK_LENGTH = 28; public const ushort TEMPLATE_ID = 51; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; @@ -96,11 +96,43 @@ public void Limit(int limit) this._limit = limit; } - public static int LogPositionEncodingOffset() + public static int LogLeadershipTermIdEncodingOffset() { return 0; } + public static int LogLeadershipTermIdEncodingLength() + { + return 8; + } + + public static long LogLeadershipTermIdNullValue() + { + return -9223372036854775808L; + } + + public static long LogLeadershipTermIdMinValue() + { + return -9223372036854775807L; + } + + public static long LogLeadershipTermIdMaxValue() + { + return 9223372036854775807L; + } + + public RequestVoteEncoder LogLeadershipTermId(long value) + { + _buffer.PutLong(_offset + 0, value, ByteOrder.LittleEndian); + return this; + } + + + public static int LogPositionEncodingOffset() + { + return 8; + } + public static int LogPositionEncodingLength() { return 8; @@ -123,14 +155,14 @@ public static long LogPositionMaxValue() public RequestVoteEncoder LogPosition(long value) { - _buffer.PutLong(_offset + 0, value, ByteOrder.LittleEndian); + _buffer.PutLong(_offset + 8, value, ByteOrder.LittleEndian); return this; } public static int CandidateTermIdEncodingOffset() { - return 8; + return 16; } public static int CandidateTermIdEncodingLength() @@ -155,14 +187,14 @@ public static long CandidateTermIdMaxValue() public RequestVoteEncoder CandidateTermId(long value) { - _buffer.PutLong(_offset + 8, value, ByteOrder.LittleEndian); + _buffer.PutLong(_offset + 16, value, ByteOrder.LittleEndian); return this; } public static int CandidateMemberIdEncodingOffset() { - return 16; + return 24; } public static int CandidateMemberIdEncodingLength() @@ -187,7 +219,7 @@ public static int CandidateMemberIdMaxValue() public RequestVoteEncoder CandidateMemberId(int value) { - _buffer.PutInt(_offset + 16, value, ByteOrder.LittleEndian); + _buffer.PutInt(_offset + 24, value, ByteOrder.LittleEndian); return this; } diff --git a/src/Adaptive.Cluster/Codecs/ScheduleTimerDecoder.cs b/src/Adaptive.Cluster/Codecs/ScheduleTimerDecoder.cs index 3bf68f06..80b97973 100644 --- a/src/Adaptive.Cluster/Codecs/ScheduleTimerDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/ScheduleTimerDecoder.cs @@ -10,7 +10,7 @@ namespace Adaptive.Cluster.Codecs { public class ScheduleTimerDecoder { public const ushort BLOCK_LENGTH = 16; - public const ushort TEMPLATE_ID = 30; + public const ushort TEMPLATE_ID = 31; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; diff --git a/src/Adaptive.Cluster/Codecs/ScheduleTimerEncoder.cs b/src/Adaptive.Cluster/Codecs/ScheduleTimerEncoder.cs index f4fa6a94..ddaf85f8 100644 --- a/src/Adaptive.Cluster/Codecs/ScheduleTimerEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/ScheduleTimerEncoder.cs @@ -10,7 +10,7 @@ namespace Adaptive.Cluster.Codecs { public class ScheduleTimerEncoder { public const ushort BLOCK_LENGTH = 16; - public const ushort TEMPLATE_ID = 30; + public const ushort TEMPLATE_ID = 31; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; diff --git a/src/Adaptive.Cluster/Codecs/ClusterActionAckDecoder.cs b/src/Adaptive.Cluster/Codecs/ServiceAckDecoder.cs similarity index 72% rename from src/Adaptive.Cluster/Codecs/ClusterActionAckDecoder.cs rename to src/Adaptive.Cluster/Codecs/ServiceAckDecoder.cs index 2b422283..67bf8b5e 100644 --- a/src/Adaptive.Cluster/Codecs/ClusterActionAckDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/ServiceAckDecoder.cs @@ -7,21 +7,21 @@ namespace Adaptive.Cluster.Codecs { -public class ClusterActionAckDecoder +public class ServiceAckDecoder { - public const ushort BLOCK_LENGTH = 24; - public const ushort TEMPLATE_ID = 32; + public const ushort BLOCK_LENGTH = 28; + public const ushort TEMPLATE_ID = 33; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; - private ClusterActionAckDecoder _parentMessage; + private ServiceAckDecoder _parentMessage; private IDirectBuffer _buffer; protected int _offset; protected int _limit; protected int _actingBlockLength; protected int _actingVersion; - public ClusterActionAckDecoder() + public ServiceAckDecoder() { _parentMessage = this; } @@ -61,7 +61,7 @@ public int Offset() return _offset; } - public ClusterActionAckDecoder Wrap( + public ServiceAckDecoder Wrap( IDirectBuffer buffer, int offset, int actingBlockLength, int actingVersion) { this._buffer = buffer; @@ -142,27 +142,27 @@ public long LogPosition() } - public static int LeadershipTermIdId() + public static int AckIdId() { return 2; } - public static int LeadershipTermIdSinceVersion() + public static int AckIdSinceVersion() { return 0; } - public static int LeadershipTermIdEncodingOffset() + public static int AckIdEncodingOffset() { return 8; } - public static int LeadershipTermIdEncodingLength() + public static int AckIdEncodingLength() { return 8; } - public static string LeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) + public static string AckIdMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -175,48 +175,48 @@ public static string LeadershipTermIdMetaAttribute(MetaAttribute metaAttribute) return ""; } - public static long LeadershipTermIdNullValue() + public static long AckIdNullValue() { return -9223372036854775808L; } - public static long LeadershipTermIdMinValue() + public static long AckIdMinValue() { return -9223372036854775807L; } - public static long LeadershipTermIdMaxValue() + public static long AckIdMaxValue() { return 9223372036854775807L; } - public long LeadershipTermId() + public long AckId() { return _buffer.GetLong(_offset + 8, ByteOrder.LittleEndian); } - public static int ServiceIdId() + public static int RelevantIdId() { return 3; } - public static int ServiceIdSinceVersion() + public static int RelevantIdSinceVersion() { return 0; } - public static int ServiceIdEncodingOffset() + public static int RelevantIdEncodingOffset() { return 16; } - public static int ServiceIdEncodingLength() + public static int RelevantIdEncodingLength() { - return 4; + return 8; } - public static string ServiceIdMetaAttribute(MetaAttribute metaAttribute) + public static string RelevantIdMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -229,48 +229,48 @@ public static string ServiceIdMetaAttribute(MetaAttribute metaAttribute) return ""; } - public static int ServiceIdNullValue() + public static long RelevantIdNullValue() { - return -2147483648; + return -9223372036854775808L; } - public static int ServiceIdMinValue() + public static long RelevantIdMinValue() { - return -2147483647; + return -9223372036854775807L; } - public static int ServiceIdMaxValue() + public static long RelevantIdMaxValue() { - return 2147483647; + return 9223372036854775807L; } - public int ServiceId() + public long RelevantId() { - return _buffer.GetInt(_offset + 16, ByteOrder.LittleEndian); + return _buffer.GetLong(_offset + 16, ByteOrder.LittleEndian); } - public static int ActionId() + public static int ServiceIdId() { return 4; } - public static int ActionSinceVersion() + public static int ServiceIdSinceVersion() { return 0; } - public static int ActionEncodingOffset() + public static int ServiceIdEncodingOffset() { - return 20; + return 24; } - public static int ActionEncodingLength() + public static int ServiceIdEncodingLength() { return 4; } - public static string ActionMetaAttribute(MetaAttribute metaAttribute) + public static string ServiceIdMetaAttribute(MetaAttribute metaAttribute) { switch (metaAttribute) { @@ -283,9 +283,24 @@ public static string ActionMetaAttribute(MetaAttribute metaAttribute) return ""; } - public ClusterAction Action() + public static int ServiceIdNullValue() + { + return -2147483648; + } + + public static int ServiceIdMinValue() + { + return -2147483647; + } + + public static int ServiceIdMaxValue() + { + return 2147483647; + } + + public int ServiceId() { - return (ClusterAction)_buffer.GetInt(_offset + 20, ByteOrder.LittleEndian); + return _buffer.GetInt(_offset + 24, ByteOrder.LittleEndian); } @@ -299,7 +314,7 @@ public StringBuilder AppendTo(StringBuilder builder) { int originalLimit = Limit(); Limit(_offset + _actingBlockLength); - builder.Append("[ClusterActionAck](sbeTemplateId="); + builder.Append("[ServiceAck](sbeTemplateId="); builder.Append(TEMPLATE_ID); builder.Append("|sbeSchemaId="); builder.Append(SCHEMA_ID); @@ -323,20 +338,20 @@ public StringBuilder AppendTo(StringBuilder builder) builder.Append("LogPosition="); builder.Append(LogPosition()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='leadershipTermId', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='ackId', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - builder.Append("LeadershipTermId="); - builder.Append(LeadershipTermId()); + builder.Append("AckId="); + builder.Append(AckId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='serviceId', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='relevantId', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("RelevantId="); + builder.Append(RelevantId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='serviceId', referencedName='null', description='null', id=4, version=0, deprecated=0, encodedLength=0, offset=24, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=24, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("ServiceId="); builder.Append(ServiceId()); - builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='action', referencedName='null', description='null', id=4, version=0, deprecated=0, encodedLength=0, offset=20, componentTokenCount=12, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=BEGIN_ENUM, name='ClusterAction', referencedName='null', description='Action to be taken by a cluster nodes', id=-1, version=0, deprecated=0, encodedLength=4, offset=20, componentTokenCount=10, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='null', timeUnit=null, semanticType='null'}} - builder.Append("Action="); - builder.Append(Action()); Limit(originalLimit); diff --git a/src/Adaptive.Cluster/Codecs/ServiceAckEncoder.cs b/src/Adaptive.Cluster/Codecs/ServiceAckEncoder.cs new file mode 100644 index 00000000..d4a4125e --- /dev/null +++ b/src/Adaptive.Cluster/Codecs/ServiceAckEncoder.cs @@ -0,0 +1,241 @@ +/* Generated SBE (Simple Binary Encoding) message codec */ +using System; +using System.Text; +using System.Collections.Generic; +using Adaptive.Agrona; + + +namespace Adaptive.Cluster.Codecs { + +public class ServiceAckEncoder +{ + public const ushort BLOCK_LENGTH = 28; + public const ushort TEMPLATE_ID = 33; + public const ushort SCHEMA_ID = 1; + public const ushort SCHEMA_VERSION = 1; + + private ServiceAckEncoder _parentMessage; + private IMutableDirectBuffer _buffer; + protected int _offset; + protected int _limit; + + public ServiceAckEncoder() + { + _parentMessage = this; + } + + public ushort SbeBlockLength() + { + return BLOCK_LENGTH; + } + + public ushort SbeTemplateId() + { + return TEMPLATE_ID; + } + + public ushort SbeSchemaId() + { + return SCHEMA_ID; + } + + public ushort SbeSchemaVersion() + { + return SCHEMA_VERSION; + } + + public string SbeSemanticType() + { + return ""; + } + + public IMutableDirectBuffer Buffer() + { + return _buffer; + } + + public int Offset() + { + return _offset; + } + + public ServiceAckEncoder Wrap(IMutableDirectBuffer buffer, int offset) + { + this._buffer = buffer; + this._offset = offset; + Limit(offset + BLOCK_LENGTH); + + return this; + } + + public ServiceAckEncoder WrapAndApplyHeader( + IMutableDirectBuffer buffer, int offset, MessageHeaderEncoder headerEncoder) + { + headerEncoder + .Wrap(buffer, offset) + .BlockLength(BLOCK_LENGTH) + .TemplateId(TEMPLATE_ID) + .SchemaId(SCHEMA_ID) + .Version(SCHEMA_VERSION); + + return Wrap(buffer, offset + MessageHeaderEncoder.ENCODED_LENGTH); + } + + public int EncodedLength() + { + return _limit - _offset; + } + + public int Limit() + { + return _limit; + } + + public void Limit(int limit) + { + this._limit = limit; + } + + public static int LogPositionEncodingOffset() + { + return 0; + } + + public static int LogPositionEncodingLength() + { + return 8; + } + + public static long LogPositionNullValue() + { + return -9223372036854775808L; + } + + public static long LogPositionMinValue() + { + return -9223372036854775807L; + } + + public static long LogPositionMaxValue() + { + return 9223372036854775807L; + } + + public ServiceAckEncoder LogPosition(long value) + { + _buffer.PutLong(_offset + 0, value, ByteOrder.LittleEndian); + return this; + } + + + public static int AckIdEncodingOffset() + { + return 8; + } + + public static int AckIdEncodingLength() + { + return 8; + } + + public static long AckIdNullValue() + { + return -9223372036854775808L; + } + + public static long AckIdMinValue() + { + return -9223372036854775807L; + } + + public static long AckIdMaxValue() + { + return 9223372036854775807L; + } + + public ServiceAckEncoder AckId(long value) + { + _buffer.PutLong(_offset + 8, value, ByteOrder.LittleEndian); + return this; + } + + + public static int RelevantIdEncodingOffset() + { + return 16; + } + + public static int RelevantIdEncodingLength() + { + return 8; + } + + public static long RelevantIdNullValue() + { + return -9223372036854775808L; + } + + public static long RelevantIdMinValue() + { + return -9223372036854775807L; + } + + public static long RelevantIdMaxValue() + { + return 9223372036854775807L; + } + + public ServiceAckEncoder RelevantId(long value) + { + _buffer.PutLong(_offset + 16, value, ByteOrder.LittleEndian); + return this; + } + + + public static int ServiceIdEncodingOffset() + { + return 24; + } + + public static int ServiceIdEncodingLength() + { + return 4; + } + + public static int ServiceIdNullValue() + { + return -2147483648; + } + + public static int ServiceIdMinValue() + { + return -2147483647; + } + + public static int ServiceIdMaxValue() + { + return 2147483647; + } + + public ServiceAckEncoder ServiceId(int value) + { + _buffer.PutInt(_offset + 24, value, ByteOrder.LittleEndian); + return this; + } + + + + public override string ToString() + { + return AppendTo(new StringBuilder(100)).ToString(); + } + + public StringBuilder AppendTo(StringBuilder builder) + { + ServiceAckDecoder writer = new ServiceAckDecoder(); + writer.Wrap(_buffer, _offset, BLOCK_LENGTH, SCHEMA_VERSION); + + return writer.AppendTo(builder); + } +} +} diff --git a/src/Adaptive.Cluster/Codecs/SessionConnectRequestDecoder.cs b/src/Adaptive.Cluster/Codecs/SessionConnectRequestDecoder.cs index d21ff11c..f93b8994 100644 --- a/src/Adaptive.Cluster/Codecs/SessionConnectRequestDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/SessionConnectRequestDecoder.cs @@ -10,7 +10,7 @@ namespace Adaptive.Cluster.Codecs { public class SessionConnectRequestDecoder { public const ushort BLOCK_LENGTH = 20; - public const ushort TEMPLATE_ID = 2; + public const ushort TEMPLATE_ID = 3; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; diff --git a/src/Adaptive.Cluster/Codecs/SessionConnectRequestEncoder.cs b/src/Adaptive.Cluster/Codecs/SessionConnectRequestEncoder.cs index 025bc81e..ac7aecb5 100644 --- a/src/Adaptive.Cluster/Codecs/SessionConnectRequestEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/SessionConnectRequestEncoder.cs @@ -10,7 +10,7 @@ namespace Adaptive.Cluster.Codecs { public class SessionConnectRequestEncoder { public const ushort BLOCK_LENGTH = 20; - public const ushort TEMPLATE_ID = 2; + public const ushort TEMPLATE_ID = 3; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; diff --git a/src/Adaptive.Cluster/Codecs/SessionEventDecoder.cs b/src/Adaptive.Cluster/Codecs/SessionEventDecoder.cs index 92b0a112..f05a321e 100644 --- a/src/Adaptive.Cluster/Codecs/SessionEventDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/SessionEventDecoder.cs @@ -9,8 +9,8 @@ namespace Adaptive.Cluster.Codecs { public class SessionEventDecoder { - public const ushort BLOCK_LENGTH = 20; - public const ushort TEMPLATE_ID = 1; + public const ushort BLOCK_LENGTH = 24; + public const ushort TEMPLATE_ID = 2; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; @@ -196,11 +196,65 @@ public long CorrelationId() } - public static int CodeId() + public static int LeaderMemberIdId() { return 3; } + public static int LeaderMemberIdSinceVersion() + { + return 0; + } + + public static int LeaderMemberIdEncodingOffset() + { + return 16; + } + + public static int LeaderMemberIdEncodingLength() + { + return 4; + } + + public static string LeaderMemberIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static int LeaderMemberIdNullValue() + { + return -2147483648; + } + + public static int LeaderMemberIdMinValue() + { + return -2147483647; + } + + public static int LeaderMemberIdMaxValue() + { + return 2147483647; + } + + public int LeaderMemberId() + { + return _buffer.GetInt(_offset + 16, ByteOrder.LittleEndian); + } + + + public static int CodeId() + { + return 4; + } + public static int CodeSinceVersion() { return 0; @@ -208,7 +262,7 @@ public static int CodeSinceVersion() public static int CodeEncodingOffset() { - return 16; + return 20; } public static int CodeEncodingLength() @@ -231,13 +285,13 @@ public static string CodeMetaAttribute(MetaAttribute metaAttribute) public EventCode Code() { - return (EventCode)_buffer.GetInt(_offset + 16, ByteOrder.LittleEndian); + return (EventCode)_buffer.GetInt(_offset + 20, ByteOrder.LittleEndian); } public static int DetailId() { - return 4; + return 5; } public static int DetailSinceVersion() @@ -349,12 +403,17 @@ public StringBuilder AppendTo(StringBuilder builder) builder.Append("CorrelationId="); builder.Append(CorrelationId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='code', referencedName='null', description='code type of the response', id=3, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=8, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=BEGIN_ENUM, name='EventCode', referencedName='null', description='Type of event for a response', id=-1, version=0, deprecated=0, encodedLength=4, offset=16, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='null', timeUnit=null, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='leaderMemberId', referencedName='null', description='current leader of the cluster', id=3, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LeaderMemberId="); + builder.Append(LeaderMemberId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='code', referencedName='null', description='code type of the response', id=4, version=0, deprecated=0, encodedLength=0, offset=20, componentTokenCount=8, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_ENUM, name='EventCode', referencedName='null', description='Type of event for a response', id=-1, version=0, deprecated=0, encodedLength=4, offset=20, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='null', timeUnit=null, semanticType='null'}} builder.Append("Code="); builder.Append(Code()); builder.Append('|'); - //Token{signal=BEGIN_VAR_DATA, name='detail', referencedName='null', description='Further detail such as an error message as necessary', id=4, version=0, deprecated=0, encodedLength=0, offset=20, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_VAR_DATA, name='detail', referencedName='null', description='Further detail such as an error message or list of cluster member endpoints', id=5, version=0, deprecated=0, encodedLength=0, offset=24, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("Detail="); builder.Append(Detail()); diff --git a/src/Adaptive.Cluster/Codecs/SessionEventEncoder.cs b/src/Adaptive.Cluster/Codecs/SessionEventEncoder.cs index 202bc1d9..9fd766d6 100644 --- a/src/Adaptive.Cluster/Codecs/SessionEventEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/SessionEventEncoder.cs @@ -9,8 +9,8 @@ namespace Adaptive.Cluster.Codecs { public class SessionEventEncoder { - public const ushort BLOCK_LENGTH = 20; - public const ushort TEMPLATE_ID = 1; + public const ushort BLOCK_LENGTH = 24; + public const ushort TEMPLATE_ID = 2; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; @@ -160,11 +160,43 @@ public SessionEventEncoder CorrelationId(long value) } - public static int CodeEncodingOffset() + public static int LeaderMemberIdEncodingOffset() { return 16; } + public static int LeaderMemberIdEncodingLength() + { + return 4; + } + + public static int LeaderMemberIdNullValue() + { + return -2147483648; + } + + public static int LeaderMemberIdMinValue() + { + return -2147483647; + } + + public static int LeaderMemberIdMaxValue() + { + return 2147483647; + } + + public SessionEventEncoder LeaderMemberId(int value) + { + _buffer.PutInt(_offset + 16, value, ByteOrder.LittleEndian); + return this; + } + + + public static int CodeEncodingOffset() + { + return 20; + } + public static int CodeEncodingLength() { return 4; @@ -172,13 +204,13 @@ public static int CodeEncodingLength() public SessionEventEncoder Code(EventCode value) { - _buffer.PutInt(_offset + 16, (int)value, ByteOrder.LittleEndian); + _buffer.PutInt(_offset + 20, (int)value, ByteOrder.LittleEndian); return this; } public static int DetailId() { - return 4; + return 5; } public static string DetailCharacterEncoding() diff --git a/src/Adaptive.Cluster/Codecs/SessionHeaderDecoder.cs b/src/Adaptive.Cluster/Codecs/SessionHeaderDecoder.cs index fb7ce7de..dde1226e 100644 --- a/src/Adaptive.Cluster/Codecs/SessionHeaderDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/SessionHeaderDecoder.cs @@ -10,7 +10,7 @@ namespace Adaptive.Cluster.Codecs { public class SessionHeaderDecoder { public const ushort BLOCK_LENGTH = 24; - public const ushort TEMPLATE_ID = 3; + public const ushort TEMPLATE_ID = 1; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; diff --git a/src/Adaptive.Cluster/Codecs/SessionHeaderEncoder.cs b/src/Adaptive.Cluster/Codecs/SessionHeaderEncoder.cs index 5e2cf770..cdce0473 100644 --- a/src/Adaptive.Cluster/Codecs/SessionHeaderEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/SessionHeaderEncoder.cs @@ -10,7 +10,7 @@ namespace Adaptive.Cluster.Codecs { public class SessionHeaderEncoder { public const ushort BLOCK_LENGTH = 24; - public const ushort TEMPLATE_ID = 3; + public const ushort TEMPLATE_ID = 1; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; diff --git a/src/Adaptive.Cluster/Codecs/VoteDecoder.cs b/src/Adaptive.Cluster/Codecs/VoteDecoder.cs index 372dbe9a..54d78555 100644 --- a/src/Adaptive.Cluster/Codecs/VoteDecoder.cs +++ b/src/Adaptive.Cluster/Codecs/VoteDecoder.cs @@ -9,7 +9,7 @@ namespace Adaptive.Cluster.Codecs { public class VoteDecoder { - public const ushort BLOCK_LENGTH = 20; + public const ushort BLOCK_LENGTH = 36; public const ushort TEMPLATE_ID = 52; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; @@ -142,11 +142,119 @@ public long CandidateTermId() } - public static int CandidateMemberIdId() + public static int LogLeaderhipTermIdId() { return 2; } + public static int LogLeaderhipTermIdSinceVersion() + { + return 0; + } + + public static int LogLeaderhipTermIdEncodingOffset() + { + return 8; + } + + public static int LogLeaderhipTermIdEncodingLength() + { + return 8; + } + + public static string LogLeaderhipTermIdMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long LogLeaderhipTermIdNullValue() + { + return -9223372036854775808L; + } + + public static long LogLeaderhipTermIdMinValue() + { + return -9223372036854775807L; + } + + public static long LogLeaderhipTermIdMaxValue() + { + return 9223372036854775807L; + } + + public long LogLeaderhipTermId() + { + return _buffer.GetLong(_offset + 8, ByteOrder.LittleEndian); + } + + + public static int LogPositionId() + { + return 3; + } + + public static int LogPositionSinceVersion() + { + return 0; + } + + public static int LogPositionEncodingOffset() + { + return 16; + } + + public static int LogPositionEncodingLength() + { + return 8; + } + + public static string LogPositionMetaAttribute(MetaAttribute metaAttribute) + { + switch (metaAttribute) + { + case MetaAttribute.EPOCH: return "unix"; + case MetaAttribute.TIME_UNIT: return "nanosecond"; + case MetaAttribute.SEMANTIC_TYPE: return ""; + case MetaAttribute.PRESENCE: return "required"; + } + + return ""; + } + + public static long LogPositionNullValue() + { + return -9223372036854775808L; + } + + public static long LogPositionMinValue() + { + return -9223372036854775807L; + } + + public static long LogPositionMaxValue() + { + return 9223372036854775807L; + } + + public long LogPosition() + { + return _buffer.GetLong(_offset + 16, ByteOrder.LittleEndian); + } + + + public static int CandidateMemberIdId() + { + return 4; + } + public static int CandidateMemberIdSinceVersion() { return 0; @@ -154,7 +262,7 @@ public static int CandidateMemberIdSinceVersion() public static int CandidateMemberIdEncodingOffset() { - return 8; + return 24; } public static int CandidateMemberIdEncodingLength() @@ -192,13 +300,13 @@ public static int CandidateMemberIdMaxValue() public int CandidateMemberId() { - return _buffer.GetInt(_offset + 8, ByteOrder.LittleEndian); + return _buffer.GetInt(_offset + 24, ByteOrder.LittleEndian); } public static int FollowerMemberIdId() { - return 3; + return 5; } public static int FollowerMemberIdSinceVersion() @@ -208,7 +316,7 @@ public static int FollowerMemberIdSinceVersion() public static int FollowerMemberIdEncodingOffset() { - return 12; + return 28; } public static int FollowerMemberIdEncodingLength() @@ -246,13 +354,13 @@ public static int FollowerMemberIdMaxValue() public int FollowerMemberId() { - return _buffer.GetInt(_offset + 12, ByteOrder.LittleEndian); + return _buffer.GetInt(_offset + 28, ByteOrder.LittleEndian); } public static int VoteId() { - return 4; + return 6; } public static int VoteSinceVersion() @@ -262,7 +370,7 @@ public static int VoteSinceVersion() public static int VoteEncodingOffset() { - return 16; + return 32; } public static int VoteEncodingLength() @@ -285,7 +393,7 @@ public static string VoteMetaAttribute(MetaAttribute metaAttribute) public BooleanType Vote() { - return (BooleanType)_buffer.GetInt(_offset + 16, ByteOrder.LittleEndian); + return (BooleanType)_buffer.GetInt(_offset + 32, ByteOrder.LittleEndian); } @@ -323,18 +431,28 @@ public StringBuilder AppendTo(StringBuilder builder) builder.Append("CandidateTermId="); builder.Append(CandidateTermId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='candidateMemberId', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='logLeaderhipTermId', referencedName='null', description='null', id=2, version=0, deprecated=0, encodedLength=0, offset=8, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=8, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LogLeaderhipTermId="); + builder.Append(LogLeaderhipTermId()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='logPosition', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int64', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=8, offset=16, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + builder.Append("LogPosition="); + builder.Append(LogPosition()); + builder.Append('|'); + //Token{signal=BEGIN_FIELD, name='candidateMemberId', referencedName='null', description='null', id=4, version=0, deprecated=0, encodedLength=0, offset=24, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=24, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("CandidateMemberId="); builder.Append(CandidateMemberId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='followerMemberId', referencedName='null', description='null', id=3, version=0, deprecated=0, encodedLength=0, offset=12, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=12, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='followerMemberId', referencedName='null', description='null', id=5, version=0, deprecated=0, encodedLength=0, offset=28, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=ENCODING, name='int32', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=28, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} builder.Append("FollowerMemberId="); builder.Append(FollowerMemberId()); builder.Append('|'); - //Token{signal=BEGIN_FIELD, name='vote', referencedName='null', description='null', id=4, version=0, deprecated=0, encodedLength=0, offset=16, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} - //Token{signal=BEGIN_ENUM, name='BooleanType', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=16, componentTokenCount=4, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='null', timeUnit=null, semanticType='null'}} + //Token{signal=BEGIN_FIELD, name='vote', referencedName='null', description='null', id=6, version=0, deprecated=0, encodedLength=0, offset=32, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}} + //Token{signal=BEGIN_ENUM, name='BooleanType', referencedName='null', description='null', id=-1, version=0, deprecated=0, encodedLength=4, offset=32, componentTokenCount=4, encoding=Encoding{presence=REQUIRED, primitiveType=INT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='null', timeUnit=null, semanticType='null'}} builder.Append("Vote="); builder.Append(Vote()); diff --git a/src/Adaptive.Cluster/Codecs/VoteEncoder.cs b/src/Adaptive.Cluster/Codecs/VoteEncoder.cs index c0429138..06f82ce1 100644 --- a/src/Adaptive.Cluster/Codecs/VoteEncoder.cs +++ b/src/Adaptive.Cluster/Codecs/VoteEncoder.cs @@ -9,7 +9,7 @@ namespace Adaptive.Cluster.Codecs { public class VoteEncoder { - public const ushort BLOCK_LENGTH = 20; + public const ushort BLOCK_LENGTH = 36; public const ushort TEMPLATE_ID = 52; public const ushort SCHEMA_ID = 1; public const ushort SCHEMA_VERSION = 1; @@ -128,11 +128,75 @@ public VoteEncoder CandidateTermId(long value) } - public static int CandidateMemberIdEncodingOffset() + public static int LogLeaderhipTermIdEncodingOffset() + { + return 8; + } + + public static int LogLeaderhipTermIdEncodingLength() + { + return 8; + } + + public static long LogLeaderhipTermIdNullValue() + { + return -9223372036854775808L; + } + + public static long LogLeaderhipTermIdMinValue() + { + return -9223372036854775807L; + } + + public static long LogLeaderhipTermIdMaxValue() + { + return 9223372036854775807L; + } + + public VoteEncoder LogLeaderhipTermId(long value) + { + _buffer.PutLong(_offset + 8, value, ByteOrder.LittleEndian); + return this; + } + + + public static int LogPositionEncodingOffset() + { + return 16; + } + + public static int LogPositionEncodingLength() { return 8; } + public static long LogPositionNullValue() + { + return -9223372036854775808L; + } + + public static long LogPositionMinValue() + { + return -9223372036854775807L; + } + + public static long LogPositionMaxValue() + { + return 9223372036854775807L; + } + + public VoteEncoder LogPosition(long value) + { + _buffer.PutLong(_offset + 16, value, ByteOrder.LittleEndian); + return this; + } + + + public static int CandidateMemberIdEncodingOffset() + { + return 24; + } + public static int CandidateMemberIdEncodingLength() { return 4; @@ -155,14 +219,14 @@ public static int CandidateMemberIdMaxValue() public VoteEncoder CandidateMemberId(int value) { - _buffer.PutInt(_offset + 8, value, ByteOrder.LittleEndian); + _buffer.PutInt(_offset + 24, value, ByteOrder.LittleEndian); return this; } public static int FollowerMemberIdEncodingOffset() { - return 12; + return 28; } public static int FollowerMemberIdEncodingLength() @@ -187,14 +251,14 @@ public static int FollowerMemberIdMaxValue() public VoteEncoder FollowerMemberId(int value) { - _buffer.PutInt(_offset + 12, value, ByteOrder.LittleEndian); + _buffer.PutInt(_offset + 28, value, ByteOrder.LittleEndian); return this; } public static int VoteEncodingOffset() { - return 16; + return 32; } public static int VoteEncodingLength() @@ -204,7 +268,7 @@ public static int VoteEncodingLength() public VoteEncoder Vote(BooleanType value) { - _buffer.PutInt(_offset + 16, (int)value, ByteOrder.LittleEndian); + _buffer.PutInt(_offset + 32, (int)value, ByteOrder.LittleEndian); return this; } diff --git a/src/Adaptive.Cluster/Service/NewActiveLogEvent.cs b/src/Adaptive.Cluster/Service/ActiveLogEvent.cs similarity index 80% rename from src/Adaptive.Cluster/Service/NewActiveLogEvent.cs rename to src/Adaptive.Cluster/Service/ActiveLogEvent.cs index faeeac79..b2d1c032 100644 --- a/src/Adaptive.Cluster/Service/NewActiveLogEvent.cs +++ b/src/Adaptive.Cluster/Service/ActiveLogEvent.cs @@ -1,27 +1,27 @@ namespace Adaptive.Cluster.Service { - internal class NewActiveLogEvent + /// + /// Event to signal a change of active log to follow. + /// + internal class ActiveLogEvent { public long leadershipTermId { get; } public int commitPositionId { get; } public int sessionId { get; } public int streamId { get; } - public bool ackBeforeImage { get; } public string channel { get; } - internal NewActiveLogEvent( + internal ActiveLogEvent( long leadershipTermId, int commitPositionId, int sessionId, int streamId, - bool ackBeforeImage, string channel) { this.leadershipTermId = leadershipTermId; this.commitPositionId = commitPositionId; this.sessionId = sessionId; this.streamId = streamId; - this.ackBeforeImage = ackBeforeImage; this.channel = channel; } @@ -32,7 +32,6 @@ public override string ToString() + ", commitPositionId=" + commitPositionId + ", sessionId=" + sessionId + ", streamId=" + streamId - + ", ackBeforeImage=" + ackBeforeImage + ", channel='" + channel + "'" + '}'; } diff --git a/src/Adaptive.Cluster/Service/BoundedLogAdapter.cs b/src/Adaptive.Cluster/Service/BoundedLogAdapter.cs index 0ef0846e..b02a5abb 100644 --- a/src/Adaptive.Cluster/Service/BoundedLogAdapter.cs +++ b/src/Adaptive.Cluster/Service/BoundedLogAdapter.cs @@ -3,6 +3,7 @@ using Adaptive.Aeron.LogBuffer; using Adaptive.Aeron.Status; using Adaptive.Agrona; +using Adaptive.Agrona.Concurrent.Status; using Adaptive.Cluster.Codecs; namespace Adaptive.Cluster.Service @@ -22,6 +23,7 @@ internal sealed class BoundedLogAdapter : IControlledFragmentHandler, IDisposabl private readonly SessionHeaderDecoder sessionHeaderDecoder = new SessionHeaderDecoder(); private readonly TimerEventDecoder timerEventDecoder = new TimerEventDecoder(); private readonly ClusterActionRequestDecoder actionRequestDecoder = new ClusterActionRequestDecoder(); + private readonly NewLeadershipTermEventDecoder newLeadershipTermEventDecoder = new NewLeadershipTermEventDecoder(); private readonly Image image; private readonly ReadableCounter upperBound; @@ -39,17 +41,22 @@ public void Dispose() { image.Subscription?.Dispose(); } - - public Image Image() + + public bool IsImageClosed() + { + return image.Closed; + } + + public long Position() { - return image; + return image.Position(); } - public bool IsCaughtUp() + public bool IsConsumed(CountersReader counters) { - return image.Position() >= upperBound.Get(); + return image.Position() >= CommitPos.GetMaxLogPosition(counters, upperBound.CounterId()); } - + public int Poll() { return image.BoundedControlledPoll(fragmentAssembler, upperBound.Get(), FRAGMENT_LIMIT); @@ -58,53 +65,102 @@ public int Poll() public ControlledFragmentHandlerAction OnFragment(IDirectBuffer buffer, int offset, int length, Header header) { messageHeaderDecoder.Wrap(buffer, offset); + int templateId = messageHeaderDecoder.TemplateId(); - switch (messageHeaderDecoder.TemplateId()) + if (templateId == SessionHeaderDecoder.TEMPLATE_ID) { - case SessionHeaderDecoder.TEMPLATE_ID: - { - sessionHeaderDecoder.Wrap(buffer, offset + MessageHeaderDecoder.ENCODED_LENGTH, messageHeaderDecoder.BlockLength(), messageHeaderDecoder.Version()); - - agent.OnSessionMessage(sessionHeaderDecoder.ClusterSessionId(), sessionHeaderDecoder.CorrelationId(), sessionHeaderDecoder.Timestamp(), buffer, offset + ClientSession.SESSION_HEADER_LENGTH, length - ClientSession.SESSION_HEADER_LENGTH, header); + sessionHeaderDecoder.Wrap( + buffer, + offset + MessageHeaderDecoder.ENCODED_LENGTH, + messageHeaderDecoder.BlockLength(), + messageHeaderDecoder.Version()); + + agent.OnSessionMessage( + sessionHeaderDecoder.ClusterSessionId(), + sessionHeaderDecoder.CorrelationId(), + sessionHeaderDecoder.Timestamp(), + buffer, + offset + ClientSession.SESSION_HEADER_LENGTH, + length - ClientSession.SESSION_HEADER_LENGTH, + header); + + return ControlledFragmentHandlerAction.CONTINUE; + } - break; - } + switch (templateId) + { case TimerEventDecoder.TEMPLATE_ID: - { - timerEventDecoder.Wrap(buffer, offset + MessageHeaderDecoder.ENCODED_LENGTH, messageHeaderDecoder.BlockLength(), messageHeaderDecoder.Version()); + timerEventDecoder.Wrap( + buffer, + offset + MessageHeaderDecoder.ENCODED_LENGTH, + messageHeaderDecoder.BlockLength(), + messageHeaderDecoder.Version()); agent.OnTimerEvent(timerEventDecoder.CorrelationId(), timerEventDecoder.Timestamp()); break; - } case SessionOpenEventDecoder.TEMPLATE_ID: - { - openEventDecoder.Wrap(buffer, offset + MessageHeaderDecoder.ENCODED_LENGTH, messageHeaderDecoder.BlockLength(), messageHeaderDecoder.Version()); + openEventDecoder.Wrap( + buffer, + offset + MessageHeaderDecoder.ENCODED_LENGTH, + messageHeaderDecoder.BlockLength(), + messageHeaderDecoder.Version()); string responseChannel = openEventDecoder.ResponseChannel(); byte[] encodedPrincipal = new byte[openEventDecoder.EncodedPrincipalLength()]; openEventDecoder.GetEncodedPrincipal(encodedPrincipal, 0, encodedPrincipal.Length); - agent.OnSessionOpen(openEventDecoder.ClusterSessionId(), openEventDecoder.Timestamp(), openEventDecoder.ResponseStreamId(), responseChannel, encodedPrincipal); + agent.OnSessionOpen( + openEventDecoder.ClusterSessionId(), + openEventDecoder.CorrelationId(), + openEventDecoder.Timestamp(), + openEventDecoder.ResponseStreamId(), + responseChannel, + encodedPrincipal); break; - } case SessionCloseEventDecoder.TEMPLATE_ID: - { - closeEventDecoder.Wrap(buffer, offset + MessageHeaderDecoder.ENCODED_LENGTH, messageHeaderDecoder.BlockLength(), messageHeaderDecoder.Version()); - - agent.OnSessionClose(closeEventDecoder.ClusterSessionId(), closeEventDecoder.Timestamp(), closeEventDecoder.CloseReason()); + closeEventDecoder.Wrap( + buffer, + offset + MessageHeaderDecoder.ENCODED_LENGTH, + messageHeaderDecoder.BlockLength(), + messageHeaderDecoder.Version()); + + agent.OnSessionClose( + closeEventDecoder.ClusterSessionId(), + closeEventDecoder.Timestamp(), + closeEventDecoder.CloseReason()); break; - } case ClusterActionRequestDecoder.TEMPLATE_ID: - { - actionRequestDecoder.Wrap(buffer, offset + MessageHeaderDecoder.ENCODED_LENGTH, messageHeaderDecoder.BlockLength(), messageHeaderDecoder.Version()); - - agent.OnServiceAction(header.Position(), actionRequestDecoder.Timestamp(), actionRequestDecoder.Action()); + actionRequestDecoder.Wrap( + buffer, + offset + MessageHeaderDecoder.ENCODED_LENGTH, + messageHeaderDecoder.BlockLength(), + messageHeaderDecoder.Version()); + + agent.OnServiceAction( + actionRequestDecoder.LogPosition(), + actionRequestDecoder.LeadershipTermId(), + actionRequestDecoder.Timestamp(), + actionRequestDecoder.Action()); + break; + + case NewLeadershipTermEventDecoder.TEMPLATE_ID: + newLeadershipTermEventDecoder.Wrap( + buffer, + offset + MessageHeaderDecoder.ENCODED_LENGTH, + messageHeaderDecoder.BlockLength(), + messageHeaderDecoder.Version()); + + agent.OnNewLeadershipTermEvent( + newLeadershipTermEventDecoder.LeadershipTermId(), + newLeadershipTermEventDecoder.LogPosition(), + newLeadershipTermEventDecoder.Timestamp(), + newLeadershipTermEventDecoder.LeaderMemberId(), + newLeadershipTermEventDecoder.LogSessionId()); break; - } } return ControlledFragmentHandlerAction.CONTINUE; diff --git a/src/Adaptive.Cluster/Service/ClientSession.cs b/src/Adaptive.Cluster/Service/ClientSession.cs index f3eb2144..3c108379 100644 --- a/src/Adaptive.Cluster/Service/ClientSession.cs +++ b/src/Adaptive.Cluster/Service/ClientSession.cs @@ -2,6 +2,7 @@ using Adaptive.Aeron; using Adaptive.Agrona; using Adaptive.Agrona.Concurrent; +using Adaptive.Cluster.Client; using Adaptive.Cluster.Codecs; namespace Adaptive.Cluster.Service @@ -14,7 +15,8 @@ public class ClientSession /// /// Length of the session header that will be prepended to the message. /// - public static readonly int SESSION_HEADER_LENGTH = MessageHeaderEncoder.ENCODED_LENGTH + SessionHeaderEncoder.BLOCK_LENGTH; + public static readonly int SESSION_HEADER_LENGTH = + MessageHeaderEncoder.ENCODED_LENGTH + SessionHeaderEncoder.BLOCK_LENGTH; /// /// Return value to indicate egress to a session is mocked out by the cluster when in follower mode. @@ -22,6 +24,7 @@ public class ClientSession public const long MOCKED_OFFER = 1; private readonly long _id; + private long _lastCorrelationId; private readonly int _responseStreamId; private readonly string _responseChannel; private Publication _responsePublication; @@ -29,12 +32,19 @@ public class ClientSession private readonly DirectBufferVector[] _vectors = new DirectBufferVector[2]; private readonly DirectBufferVector _messageBuffer = new DirectBufferVector(); private readonly SessionHeaderEncoder _sessionHeaderEncoder = new SessionHeaderEncoder(); - private readonly ICluster _cluster; + private readonly ClusteredServiceAgent _cluster; private bool _isClosing; - internal ClientSession(long sessionId, int responseStreamId, string responseChannel, byte[] encodedPrincipal, ICluster cluster) + internal ClientSession( + long sessionId, + long correlationId, + int responseStreamId, + string responseChannel, + byte[] encodedPrincipal, + ClusteredServiceAgent cluster) { _id = sessionId; + _lastCorrelationId = correlationId; _responseStreamId = responseStreamId; _responseChannel = responseChannel; _encodedPrincipal = encodedPrincipal; @@ -88,6 +98,15 @@ public byte[] EncodedPrincipal() /// /// whether a request to close this session has been made. public bool IsClosing => _isClosing; + + /// + /// Get the last correlation id processed on this session. + /// + /// the last correlation id processed on this session. + public long LastCorrelationId() + { + return _lastCorrelationId; + } /// /// Non-blocking publish of a partial buffer containing a message to a cluster. @@ -98,15 +117,62 @@ public byte[] EncodedPrincipal() /// in bytes of the encoded message. /// the same as when in /// otherwise . - public long Offer(long correlationId, IDirectBuffer buffer, int offset, int length) + public long Offer( + long correlationId, + IDirectBuffer buffer, + int offset, + int length) + { + if (_cluster.Role() != ClusterRole.Leader) + { + return MOCKED_OFFER; + } + + if (null == _responsePublication) + { + throw new ClusterException("session not connected id=" + _id); + } + + _sessionHeaderEncoder + .CorrelationId(correlationId) + .Timestamp(_cluster.TimeMs()); + + _messageBuffer.Reset(buffer, offset, length); + + return _responsePublication.Offer(_vectors); + } + + /// + /// Non-blocking publish of a partial buffer containing a message to a cluster. + /// + /// to be used to identify the message to the cluster. + /// to be used for when the response was generated. + /// containing message. + /// offset in the buffer at which the encoded message begins. + /// in bytes of the encoded message. + /// the same as when in + /// otherwise . + public long Offer( + long correlationId, + long timestampMs, + IDirectBuffer buffer, + int offset, + int length) { if (_cluster.Role() != ClusterRole.Leader) { return MOCKED_OFFER; } - _sessionHeaderEncoder.CorrelationId(correlationId); - _sessionHeaderEncoder.Timestamp(_cluster.TimeMs()); + if (null == _responsePublication) + { + throw new ClusterException("session not connected id=" + _id); + } + + _sessionHeaderEncoder + .CorrelationId(correlationId) + .Timestamp(timestampMs); + _messageBuffer.Reset(buffer, offset, length); return _responsePublication.Offer(_vectors); @@ -125,10 +191,20 @@ internal void MarkClosing() _isClosing = true; } + internal void ResetClosing() + { + _isClosing = false; + } + internal void Disconnect() { _responsePublication?.Dispose(); _responsePublication = null; } + + internal void LastCorrelationId(long correlationId) + { + _lastCorrelationId = correlationId; + } } } \ No newline at end of file diff --git a/src/Adaptive.Cluster/Service/ClusterMarkFile.cs b/src/Adaptive.Cluster/Service/ClusterMarkFile.cs index 78b2fa8b..224413c7 100644 --- a/src/Adaptive.Cluster/Service/ClusterMarkFile.cs +++ b/src/Adaptive.Cluster/Service/ClusterMarkFile.cs @@ -4,6 +4,7 @@ using Adaptive.Agrona; using Adaptive.Agrona.Concurrent; using Adaptive.Agrona.Concurrent.Errors; +using Adaptive.Cluster.Client; using Adaptive.Cluster.Codecs.Mark; namespace Adaptive.Cluster @@ -15,7 +16,10 @@ namespace Adaptive.Cluster /// public class ClusterMarkFile : IDisposable { - public const string FILENAME = "cluster-mark.dat"; + public const string FILE_EXTENSION = ".dat"; + public const string FILENAME = "cluster-mark" + FILE_EXTENSION; + public const string SERVICE_FILE_NAME_PREFIX = "cluster-mark-service-"; + public const string SERVICE_FILE_NAME_FORMAT = SERVICE_FILE_NAME_PREFIX + "{0}" + FILE_EXTENSION; public const int HEADER_LENGTH = 8 * 1024; private readonly MarkFileHeaderDecoder headerDecoder = new MarkFileHeaderDecoder(); @@ -45,7 +49,7 @@ public ClusterMarkFile( { if (version != MarkFileHeaderDecoder.SCHEMA_VERSION) { - throw new ArgumentException("mark file version " + version + " does not match software:" + MarkFileHeaderDecoder.SCHEMA_VERSION); + throw new ClusterException("mark file version " + version + " does not match software:" + MarkFileHeaderDecoder.SCHEMA_VERSION); } }, null); @@ -66,6 +70,10 @@ public ClusterMarkFile( errorBuffer.SetMemory(0, errorBufferLength, 0); } + else + { + headerEncoder.CandidateTermId(Aeron.Aeron.NULL_VALUE); + } var existingType = headerDecoder.ComponentType(); @@ -78,6 +86,7 @@ public ClusterMarkFile( headerEncoder.HeaderLength(HEADER_LENGTH); headerEncoder.ErrorBufferLength(errorBufferLength); headerEncoder.Pid(Process.GetCurrentProcess().Id); + headerEncoder.StartTimestamp(epochClock.Time()); } public ClusterMarkFile(DirectoryInfo directory, string filename, IEpochClock epochClock, long timeoutMs, Action logger) @@ -107,6 +116,27 @@ public void Dispose() { markFile?.Dispose(); } + + /// + /// Get the current value of a candidate term id if a vote is placed in an election. + /// + /// the current candidate term id within an election after voting or if + /// no voting phase of an election is currently active. + public long CandidateTermId() + { + return buffer.GetLongVolatile(MarkFileHeaderDecoder.CandidateTermIdEncodingOffset()); + } + + /// + /// Record the fact that a node has voted in a current election for a candidate so it can survive a restart. + /// + /// to record that a vote has taken place. + public void CandidateTermId(long candidateTermId) + { + buffer.PutLongVolatile(MarkFileHeaderEncoder.CandidateTermIdEncodingOffset(), candidateTermId); + //markFile.MappedByteBuffer().Force(); How to do this? + } + public void SignalReady() { @@ -198,8 +228,13 @@ public static void CheckHeaderLength( if (lengthRequired > HEADER_LENGTH) { - throw new ArgumentException($"MarkFile length required {lengthRequired} great than {HEADER_LENGTH}."); + throw new ClusterException($"MarkFile length required {lengthRequired} great than {HEADER_LENGTH}."); } } + + public static string MarkFilenameForService(int serviceId) + { + return string.Format(SERVICE_FILE_NAME_FORMAT, serviceId); + } } } \ No newline at end of file diff --git a/src/Adaptive.Cluster/Service/ClusteredServiceAgent.cs b/src/Adaptive.Cluster/Service/ClusteredServiceAgent.cs index 429af28a..e9fe068c 100644 --- a/src/Adaptive.Cluster/Service/ClusteredServiceAgent.cs +++ b/src/Adaptive.Cluster/Service/ClusteredServiceAgent.cs @@ -8,35 +8,33 @@ using Adaptive.Agrona.Concurrent; using Adaptive.Agrona.Concurrent.Status; using Adaptive.Archiver; +using Adaptive.Cluster.Client; using Adaptive.Cluster.Codecs; namespace Adaptive.Cluster.Service { - internal sealed class ClusteredServiceAgent : IAgent, ICluster, IServiceControlListener + internal sealed class ClusteredServiceAgent : IAgent, ICluster { private readonly int serviceId; private bool isRecovering; - private readonly bool shouldCloseResources; private readonly AeronArchive.Context archiveCtx; private readonly ClusteredServiceContainer.Context ctx; private readonly Aeron.Aeron aeron; private readonly Dictionary sessionByIdMap = new Dictionary(); private readonly IClusteredService service; - private readonly ServiceControlPublisher serviceControlPublisher; - private readonly ServiceControlAdapter serviceControlAdapter; + private readonly ConsensusModuleProxy _consensusModuleProxy; + private readonly ServiceAdapter _serviceAdapter; private readonly IIdleStrategy idleStrategy; - private readonly RecordingLog recordingLog; private readonly IEpochClock epochClock; - private readonly CachedEpochClock cachedEpochClock = new CachedEpochClock(); private readonly ClusterMarkFile markFile; - private long termBaseLogPosition; - private long leadershipTermId; - private long timestampMs; + private long ackId = 0; + private long clusterTimeMs; + private long cachedTimeMs; private BoundedLogAdapter logAdapter; - private NewActiveLogEvent newActiveLogEvent; - private ReadableCounter roleCounter; + private ActiveLogEvent _activeLogEvent; private AtomicCounter heartbeatCounter; + private ReadableCounter roleCounter; private ClusterRole role = ClusterRole.Follower; internal ClusteredServiceAgent(ClusteredServiceContainer.Context ctx) @@ -45,9 +43,7 @@ internal ClusteredServiceAgent(ClusteredServiceContainer.Context 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(); @@ -55,21 +51,20 @@ internal ClusteredServiceAgent(ClusteredServiceContainer.Context ctx) var channel = ctx.ServiceControlChannel(); - var streamId = ctx.ServiceControlStreamId(); - - serviceControlPublisher = new ServiceControlPublisher(aeron.AddPublication(channel, streamId)); - serviceControlAdapter = new ServiceControlAdapter(aeron.AddSubscription(channel, streamId), this); + _consensusModuleProxy = new ConsensusModuleProxy(aeron.AddPublication(channel, ctx.ConsensusModuleStreamId())); + _serviceAdapter = new ServiceAdapter(aeron.AddSubscription(channel, ctx.ServiceStreamId()), this); } public void OnStart() { CountersReader counters = aeron.CountersReader(); roleCounter = AwaitClusterRoleCounter(counters); - FindHeartbeatCounter(counters); - + heartbeatCounter = AwaitHeartbeatCounter(counters); + service.OnStart(this); isRecovering = true; int recoveryCounterId = AwaitRecoveryCounter(counters); + heartbeatCounter.SetOrdered(epochClock.Time()); CheckForSnapshot(counters, recoveryCounterId); CheckForReplay(counters, recoveryCounterId); isRecovering = false; @@ -78,11 +73,11 @@ public void OnStart() public void OnClose() { - if (shouldCloseResources) + if (!ctx.OwnsAeronClient()) { logAdapter?.Dispose(); - serviceControlPublisher?.Dispose(); - serviceControlAdapter?.Dispose(); + _consensusModuleProxy?.Dispose(); + _serviceAdapter?.Dispose(); foreach (ClientSession session in sessionByIdMap.Values) { @@ -94,23 +89,53 @@ public void OnClose() public int DoWork() { int workCount = 0; - + long nowMs = epochClock.Time(); - if (cachedEpochClock.Time() != nowMs) + if (cachedTimeMs != nowMs) { - cachedEpochClock.Update(nowMs); - markFile.UpdateActivityTimestamp(nowMs); - CheckHealthAndUpdateHeartbeat(nowMs); - workCount += serviceControlAdapter.Poll(); + cachedTimeMs = nowMs; + + if (_consensusModuleProxy.IsConnected()) + { + markFile.UpdateActivityTimestamp(nowMs); + heartbeatCounter.SetOrdered(nowMs); + } + else + { + ctx.ErrorHandler()(new ClusterException("Consensus Module not connected")); + ctx.TerminationHook().Invoke(); + } + + workCount += _serviceAdapter.Poll(); - if (newActiveLogEvent != null) + if (null != _activeLogEvent && null == logAdapter) { JoinActiveLog(); } } - workCount += null != logAdapter ? logAdapter.Poll() : 0; - + if (null != logAdapter) + { + int polled = logAdapter.Poll(); + + if (0 == polled) + { + if (logAdapter.IsConsumed(aeron.CountersReader())) + { + _consensusModuleProxy.Ack(logAdapter.Position(), ackId++, serviceId); + logAdapter.Dispose(); + logAdapter = null; + } + else if (logAdapter.IsImageClosed()) + { + logAdapter.Dispose(); + logAdapter = null; + } + } + + workCount += polled; + } + return workCount; } @@ -143,7 +168,7 @@ public bool CloseSession(long clusterSessionId) { if (!sessionByIdMap.ContainsKey(clusterSessionId)) { - throw new ArgumentException("unknown clusterSessionId: " + clusterSessionId); + throw new ClusterException("unknown clusterSessionId: " + clusterSessionId); } ClientSession clientSession = sessionByIdMap[clusterSessionId]; @@ -153,7 +178,7 @@ public bool CloseSession(long clusterSessionId) return true; } - if (serviceControlPublisher.CloseSession(clusterSessionId)) + if (_consensusModuleProxy.CloseSession(clusterSessionId)) { clientSession.MarkClosing(); return true; @@ -164,32 +189,23 @@ public bool CloseSession(long clusterSessionId) public long TimeMs() { - return timestampMs; + return clusterTimeMs; } public bool ScheduleTimer(long correlationId, long deadlineMs) { - return serviceControlPublisher.ScheduleTimer(correlationId, deadlineMs); + return _consensusModuleProxy.ScheduleTimer(correlationId, deadlineMs); } public bool CancelTimer(long correlationId) { - return serviceControlPublisher.CancelTimer(correlationId); + return _consensusModuleProxy.CancelTimer(correlationId); } - public void OnScheduleTimer(long correlationId, long deadline) + public void Idle() { - // Not Implemented - } - - public void OnCancelTimer(long correlationId) - { - // Not Implemented - } - - public void OnServiceAck(long logPosition, long leadershipTermId, int serviceId, ClusterAction action) - { - // Not Implemented + CheckInterruptedStatus(); + idleStrategy.Idle(); } public void OnJoinLog( @@ -197,40 +213,47 @@ public void OnJoinLog( int commitPositionId, int logSessionId, int logStreamId, - bool ackBeforeImage, string logChannel) { - newActiveLogEvent = new NewActiveLogEvent( - leadershipTermId, commitPositionId, logSessionId, logStreamId, ackBeforeImage, logChannel); - } - - public void OnServiceCloseSession(long clusterSessionId) - { - // Not Implemented + _activeLogEvent = new ActiveLogEvent( + leadershipTermId, commitPositionId, logSessionId, logStreamId, logChannel); } internal void OnSessionMessage(long clusterSessionId, long correlationId, long timestampMs, IDirectBuffer buffer, int offset, int length, Header header) { - this.timestampMs = timestampMs; + clusterTimeMs = timestampMs; + var clientSession = sessionByIdMap[clusterSessionId]; - service.OnSessionMessage(clusterSessionId, correlationId, timestampMs, buffer, offset, length, header); + try + { + service.OnSessionMessage(clientSession, correlationId, timestampMs, buffer, offset, length, header); + } + finally + { + clientSession.LastCorrelationId(correlationId); + } } internal void OnTimerEvent(long correlationId, long timestampMs) { - this.timestampMs = timestampMs; + clusterTimeMs = timestampMs; service.OnTimerEvent(correlationId, timestampMs); } - internal void OnSessionOpen(long clusterSessionId, long timestampMs, int responseStreamId, - string responseChannel, byte[] encodedPrincipal) + internal void OnSessionOpen( + long clusterSessionId, + long correlationId, + long timestampMs, + int responseStreamId, + string responseChannel, + byte[] encodedPrincipal) { - this.timestampMs = timestampMs; + clusterTimeMs = timestampMs; - ClientSession session = - new ClientSession(clusterSessionId, responseStreamId, responseChannel, encodedPrincipal, this); + ClientSession session = new ClientSession( + clusterSessionId, correlationId, responseStreamId, responseChannel, encodedPrincipal, this); if (ClusterRole.Leader == role) { @@ -243,7 +266,7 @@ internal void OnSessionOpen(long clusterSessionId, long timestampMs, int respons internal void OnSessionClose(long clusterSessionId, long timestampMs, CloseReason closeReason) { - this.timestampMs = timestampMs; + clusterTimeMs = timestampMs; var session = sessionByIdMap[clusterSessionId]; sessionByIdMap.Remove(clusterSessionId); @@ -251,28 +274,34 @@ internal void OnSessionClose(long clusterSessionId, long timestampMs, CloseReaso service.OnSessionClose(session, timestampMs, closeReason); } - internal void OnServiceAction(long termPosition, long timestampMs, ClusterAction action) + internal void OnServiceAction(long logPosition, long leadershipTermId, long timestampMs, ClusterAction action) { - this.timestampMs = timestampMs; + clusterTimeMs = timestampMs; - ExecuteAction(action, termPosition); + ExecuteAction(action, logPosition, leadershipTermId); } - internal void AddSession(long clusterSessionId, int responseStreamId, string responseChannel, - byte[] encodedPrincipal) + internal void OnNewLeadershipTermEvent( + long leadershipTermId, + long logPosition, + long timestampMs, + int leaderMemberId, + int logSessionId) { - ClientSession session = - new ClientSession(clusterSessionId, responseStreamId, responseChannel, encodedPrincipal, this); - - sessionByIdMap[clusterSessionId] = session; + clusterTimeMs = timestampMs; } - private void CheckHealthAndUpdateHeartbeat(long nowMs) + internal void AddSession( + long clusterSessionId, + long lastCorrelationId, + int responseStreamId, + string responseChannel, + byte[] encodedPrincipal) { - if (null == logAdapter || !logAdapter.Image().Closed) - { - heartbeatCounter.SetOrdered(nowMs); - } + var session = new ClientSession( + clusterSessionId, lastCorrelationId, responseStreamId, responseChannel, encodedPrincipal, this); + + sessionByIdMap[clusterSessionId] = session; } private void Role(ClusterRole newRole) @@ -286,73 +315,54 @@ private void Role(ClusterRole newRole) private void CheckForSnapshot(CountersReader counters, int recoveryCounterId) { - long termPosition = RecoveryState.GetTermPosition(counters, recoveryCounterId); - leadershipTermId = RecoveryState.GetLeadershipTermId(counters, recoveryCounterId); - timestampMs = RecoveryState.GetTimestamp(counters, recoveryCounterId); + long leadershipTermId = RecoveryState.GetLeadershipTermId(counters, recoveryCounterId); + clusterTimeMs = RecoveryState.GetTimestamp(counters, recoveryCounterId); - if (AeronArchive.NULL_POSITION != termPosition) + if (Adaptive.Aeron.Aeron.NULL_VALUE != leadershipTermId) { - RecordingLog.Entry snapshotEntry = recordingLog.GetSnapshot(leadershipTermId, termPosition); - if (null == snapshotEntry) - { - throw new InvalidOperationException( - "no snapshot available for term position: " + termPosition); - } - - termBaseLogPosition = snapshotEntry.termBaseLogPosition + snapshotEntry.termPosition; - LoadSnapshot(snapshotEntry.recordingId); + LoadSnapshot(RecoveryState.GetSnapshotRecordingId(counters, recoveryCounterId, serviceId)); } - serviceControlPublisher.AckAction(termBaseLogPosition, leadershipTermId, serviceId, ClusterAction.INIT); + heartbeatCounter.SetOrdered(epochClock.Time()); + _consensusModuleProxy.Ack(RecoveryState.GetLogPosition(counters, recoveryCounterId), ackId++, serviceId); } private void CheckForReplay(CountersReader counters, int recoveryCounterId) { - long replayTermCount = RecoveryState.GetReplayTermCount(counters, recoveryCounterId); - if (0 == replayTermCount) - { - return; - } - - service.OnReplayBegin(); - - for (int i = 0; i < replayTermCount; i++) + if (RecoveryState.HasReplay(counters, recoveryCounterId)) { + service.OnReplayBegin(); AwaitActiveLog(); - int counterId = newActiveLogEvent.commitPositionId; - leadershipTermId = CommitPos.GetLeadershipTermId(counters, counterId); - termBaseLogPosition = CommitPos.GetTermBaseLogPosition(counters, counterId); // TODO MARK - if (CommitPos.GetLeadershipTermLength(counters, counterId) > 0) - { - using (Subscription subscription = aeron.AddSubscription(newActiveLogEvent.channel, newActiveLogEvent.streamId)) - { - serviceControlPublisher.AckAction(termBaseLogPosition, leadershipTermId, serviceId, ClusterAction.READY); + int counterId = _activeLogEvent.commitPositionId; - Image image = AwaitImage(newActiveLogEvent.sessionId, subscription); - ReadableCounter limit = new ReadableCounter(counters, counterId); - BoundedLogAdapter adapter = new BoundedLogAdapter(image, limit, this); + using (Subscription subscription = aeron.AddSubscription(_activeLogEvent.channel, _activeLogEvent.streamId)) + { + _consensusModuleProxy.Ack(CommitPos.GetLogPosition(counters, counterId), ackId++, serviceId); - ConsumeImage(image, adapter); + Image image = AwaitImage(_activeLogEvent.sessionId, subscription); + ReadableCounter limit = new ReadableCounter(counters, counterId); + BoundedLogAdapter adapter = new BoundedLogAdapter(image, limit, this); - termBaseLogPosition += image.Position(); - } + ConsumeImage(image, adapter); } - newActiveLogEvent = null; - serviceControlPublisher.AckAction(termBaseLogPosition, leadershipTermId, serviceId, ClusterAction.REPLAY); + _activeLogEvent = null; + heartbeatCounter.SetOrdered(epochClock.Time()); + service.OnReplayEnd(); } - - service.OnReplayEnd(); } private void AwaitActiveLog() { - while (null == newActiveLogEvent) + idleStrategy.Reset(); + + while (null == _activeLogEvent) { + _serviceAdapter.Poll(); CheckInterruptedStatus(); - idleStrategy.Idle(serviceControlAdapter.Poll()); + idleStrategy.Idle(); } } @@ -363,19 +373,19 @@ private void ConsumeImage(Image image, BoundedLogAdapter adapter) int workCount = adapter.Poll(); if (workCount == 0) { - if (image.Closed) + if (adapter.IsConsumed(aeron.CountersReader())) { - if (!image.IsEndOfStream()) - { - throw new InvalidOperationException("unexpected close of replay"); - } - + _consensusModuleProxy.Ack(image.Position(), ackId++, serviceId); break; } - CheckInterruptedStatus(); + if (image.Closed) + { + throw new ClusterException("unexpected close of replay"); + } } + CheckInterruptedStatus(); idleStrategy.Idle(workCount); } } @@ -397,55 +407,30 @@ private int AwaitRecoveryCounter(CountersReader counters) private void JoinActiveLog() { - if (null != logAdapter) - { - if (!logAdapter.IsCaughtUp()) - { - return; - } - - logAdapter.Dispose(); - logAdapter = null; - } - - CountersReader counters = aeron.CountersReader(); - - int commitPositionId = newActiveLogEvent.commitPositionId; + int commitPositionId = _activeLogEvent.commitPositionId; if (!CommitPos.IsActive(counters, commitPositionId)) { - throw new System.InvalidOperationException("CommitPos counter not active: " + commitPositionId); + throw new ClusterException("CommitPos counter not active: " + commitPositionId); } - int logSessionId = newActiveLogEvent.sessionId; - leadershipTermId = newActiveLogEvent.leadershipTermId; - termBaseLogPosition = CommitPos.GetTermBaseLogPosition(counters, commitPositionId); + Subscription logSubscription = aeron.AddSubscription(_activeLogEvent.channel, _activeLogEvent.streamId); + _consensusModuleProxy.Ack(CommitPos.GetLogPosition(counters, commitPositionId), ackId++, serviceId); - Subscription logSubscription = aeron.AddSubscription(newActiveLogEvent.channel, newActiveLogEvent.streamId); - - if (newActiveLogEvent.ackBeforeImage) - { - serviceControlPublisher.AckAction(termBaseLogPosition, leadershipTermId, serviceId, ClusterAction.READY); - } - - Image image = AwaitImage(logSessionId, logSubscription); + Image image = AwaitImage(_activeLogEvent.sessionId, logSubscription); heartbeatCounter.SetOrdered(epochClock.Time()); - if (!newActiveLogEvent.ackBeforeImage) - { - serviceControlPublisher.AckAction(termBaseLogPosition, leadershipTermId, serviceId, ClusterAction.READY); - } - - newActiveLogEvent = null; + _activeLogEvent = null; logAdapter = new BoundedLogAdapter(image, new ReadableCounter(counters, commitPositionId), this); Role((ClusterRole) roleCounter.Get()); - + foreach (ClientSession session in sessionByIdMap.Values) { if (ClusterRole.Leader == role) { session.Connect(aeron); + session.ResetClosing(); } else { @@ -480,6 +465,20 @@ private ReadableCounter AwaitClusterRoleCounter(CountersReader counters) return new ReadableCounter(counters, counterId); } + + private AtomicCounter AwaitHeartbeatCounter(CountersReader counters) + { + idleStrategy.Reset(); + int counterId = ServiceHeartbeat.FindCounterId(counters, ctx.ServiceId()); + while (CountersReader.NULL_COUNTER_ID == counterId) + { + CheckInterruptedStatus(); + idleStrategy.Idle(); + counterId = ServiceHeartbeat.FindCounterId(counters, ctx.ServiceId()); + } + + return new AtomicCounter(counters.ValuesBuffer, counterId); + } private void LoadSnapshot(long recordingId) { @@ -487,7 +486,7 @@ private void LoadSnapshot(long recordingId) { string channel = ctx.ReplayChannel(); int streamId = ctx.ReplayStreamId(); - int sessionId = (int) archive.StartReplay(recordingId, 0, AeronArchive.NULL_LENGTH, channel, streamId); + int sessionId = (int) archive.StartReplay(recordingId, 0, Adaptive.Aeron.Aeron.NULL_VALUE, channel, streamId); string replaySessionChannel = ChannelUri.AddSessionId(channel, sessionId); using (Subscription subscription = aeron.AddSubscription(replaySessionChannel, streamId)) @@ -516,7 +515,7 @@ private void LoadState(Image image) if (image.Closed) { - throw new InvalidOperationException("snapshot ended unexpectedly"); + throw new ClusterException("snapshot ended unexpectedly"); } idleStrategy.Idle(fragments); @@ -524,22 +523,20 @@ private void LoadState(Image image) } } - private void OnTakeSnapshot(long termPosition) + private long OnTakeSnapshot(long logPosition, long leadershipTermId) { long recordingId; - string channel = ctx.SnapshotChannel(); - int streamId = ctx.SnapshotStreamId(); - using (AeronArchive archive = AeronArchive.Connect(archiveCtx)) - using (Publication publication = archive.AddRecordedExclusivePublication(channel, streamId)) + using (AeronArchive archive = AeronArchive.Connect(archiveCtx)) + using(Publication publication = archive.AddRecordedExclusivePublication(ctx.SnapshotChannel(), ctx.SnapshotStreamId())) { try { CountersReader counters = aeron.CountersReader(); - int counterId = AwaitRecordingCounter(publication, counters); + int counterId = AwaitRecordingCounter(publication.SessionId, counters); recordingId = RecordingPos.GetRecordingId(counters, counterId); - SnapshotState(publication, termBaseLogPosition + termPosition); + SnapshotState(publication, logPosition, leadershipTermId); service.OnTakeSnapshot(publication); AwaitRecordingComplete(recordingId, publication.Position, counters, counterId, archive); @@ -550,12 +547,12 @@ private void OnTakeSnapshot(long termPosition) } } - recordingLog.AppendSnapshot(recordingId, leadershipTermId, termBaseLogPosition, termPosition, timestampMs); + return recordingId; } private void AwaitRecordingComplete( long recordingId, - long completePosition, + long position, CountersReader counters, int counterId, AeronArchive archive) @@ -568,15 +565,15 @@ private void AwaitRecordingComplete( if (!RecordingPos.IsActive(counters, counterId, recordingId)) { - throw new InvalidOperationException("recording has stopped unexpectedly: " + recordingId); + throw new ClusterException("recording has stopped unexpectedly: " + recordingId); } archive.CheckForErrorResponse(); - } while (counters.GetCounterValue(counterId) < completePosition); + } while (counters.GetCounterValue(counterId) < position); } - private void SnapshotState(Publication publication, long logPosition) + private void SnapshotState(Publication publication, long logPosition, long leadershipTermId) { var snapshotTaker = new ServiceSnapshotTaker(publication, idleStrategy, null); @@ -590,61 +587,45 @@ private void SnapshotState(Publication publication, long logPosition) snapshotTaker.MarkEnd(ClusteredServiceContainer.SNAPSHOT_TYPE_ID, logPosition, leadershipTermId, 0); } - private void ExecuteAction(ClusterAction action, long termPosition) + private void ExecuteAction(ClusterAction action, long position, long leadershipTermId) { if (isRecovering) { return; } - long logPosition = termBaseLogPosition + termPosition; - switch (action) { case ClusterAction.SNAPSHOT: - OnTakeSnapshot(termPosition); - serviceControlPublisher.AckAction(logPosition, leadershipTermId, serviceId, action); + _consensusModuleProxy.Ack(position, ackId++, OnTakeSnapshot(position, leadershipTermId), serviceId); break; case ClusterAction.SHUTDOWN: - OnTakeSnapshot(termPosition); - serviceControlPublisher.AckAction(logPosition, leadershipTermId, serviceId, action); + _consensusModuleProxy.Ack(position, ackId++, OnTakeSnapshot(position, leadershipTermId), serviceId); ctx.TerminationHook().Invoke(); break; case ClusterAction.ABORT: - serviceControlPublisher.AckAction(logPosition, leadershipTermId, serviceId, action); + _consensusModuleProxy.Ack(position, ackId++, serviceId); ctx.TerminationHook().Invoke(); break; } } - private int AwaitRecordingCounter(Publication publication, CountersReader counters) + private int AwaitRecordingCounter(int sessionId, CountersReader counters) { idleStrategy.Reset(); - int counterId = RecordingPos.FindCounterIdBySession(counters, publication.SessionId); + int counterId = RecordingPos.FindCounterIdBySession(counters, sessionId); while (CountersReader.NULL_COUNTER_ID == counterId) { CheckInterruptedStatus(); idleStrategy.Idle(); - counterId = RecordingPos.FindCounterIdBySession(counters, publication.SessionId); + counterId = RecordingPos.FindCounterIdBySession(counters, sessionId); } return counterId; } - private void FindHeartbeatCounter(CountersReader counters) - { - var heartbeatCounterId = ServiceHeartbeat.FindCounterId(counters, ctx.ServiceId()); - - if (CountersReader.NULL_COUNTER_ID == heartbeatCounterId) - { - throw new InvalidOperationException("failed to find heartbeat counter"); - } - - heartbeatCounter = new AtomicCounter(counters.ValuesBuffer, heartbeatCounterId); - } - private static void CheckInterruptedStatus() { try diff --git a/src/Adaptive.Cluster/Service/ClusteredServiceContainer.cs b/src/Adaptive.Cluster/Service/ClusteredServiceContainer.cs index a7098f9e..bdabfb7f 100644 --- a/src/Adaptive.Cluster/Service/ClusteredServiceContainer.cs +++ b/src/Adaptive.Cluster/Service/ClusteredServiceContainer.cs @@ -6,6 +6,7 @@ using Adaptive.Agrona.Concurrent.Errors; using Adaptive.Agrona.Concurrent.Status; using Adaptive.Archiver; +using Adaptive.Cluster.Client; using Adaptive.Cluster.Codecs; using Adaptive.Cluster.Codecs.Mark; @@ -33,7 +34,7 @@ public static void Main(string[] args) { container.Ctx().ShutdownSignalBarrier().Await(); - Console.WriteLine("Shutdown ClusteredMediaDriver..."); + Console.WriteLine("Shutdown ClusteredServiceContainer..."); } } @@ -97,7 +98,7 @@ public class Configuration public const string SERVICE_ID_PROP_NAME = "aeron.cluster.service.id"; /// - /// Identity for a clustered service. Default to 0. + /// Default identity for a clustered service. /// public const int SERVICE_ID_DEFAULT = 0; @@ -107,7 +108,7 @@ public class Configuration public const string SERVICE_NAME_PROP_NAME = "aeron.cluster.service.name"; /// - /// Name for a clustered service to be the role of the . Default to "clustered-service". + /// Name for a clustered service to be the role of the . /// public const string SERVICE_NAME_DEFAULT = "clustered-service"; @@ -118,7 +119,7 @@ public class Configuration public const string SERVICE_CLASS_NAME_PROP_NAME = "aeron.cluster.service.class.name"; /// - /// Channel to be used for log or snapshot replay on startup. + /// Default channel to be used for log or snapshot replay on startup. /// public const string REPLAY_CHANNEL_PROP_NAME = "aeron.cluster.replay.channel"; @@ -133,33 +134,42 @@ public class Configuration public const string REPLAY_STREAM_ID_PROP_NAME = "aeron.cluster.replay.stream.id"; /// - /// Stream id for the log or snapshot replay within a channel. + /// Default stream id for the log or snapshot replay within a channel. /// - public const int REPLAY_STREAM_ID_DEFAULT = 4; + public const int REPLAY_STREAM_ID_DEFAULT = 103; /// - /// Channel for bi-directional communications between the consensus module and services. + /// Channel for communications between the local consensus module and services. /// public const string SERVICE_CONTROL_CHANNEL_PROP_NAME = "aeron.cluster.service.control.channel"; /// - /// Channel for for bi-directional communications between the consensus module and services. This should be IPC. + /// Default channel for communications between the local consensus module and services. This should be IPC. /// - public const string SERVICE_CONTROL_CHANNEL_DEFAULT = "aeron:ipc?term-length=64k"; + public const string SERVICE_CONTROL_CHANNEL_DEFAULT = "aeron:ipc?term-length=64k|mtu=8k"; /// - /// Stream id within a channel for bi-directional communications between the consensus module and services. + /// Stream id within a channel for communications from the consensus module to the services. /// - public const string SERVICE_CONTROL_STREAM_ID_PROP_NAME = "aeron.cluster.service.control.stream.id"; + public const string SERVICE_STREAM_ID_PROP_NAME = "aeron.cluster.service.stream.id"; /// - /// Stream id within a channel for bi-directional communications between the consensus module and services. - /// Default to stream id of 5. + /// Default stream id within a channel for communications from the consensus module to the services. /// - public const int CONSENSUS_MODULE_STREAM_ID_DEFAULT = 5; + public const int SERVICE_CONTROL_STREAM_ID_DEFAULT = 104; /// - /// Channel to be used for archiving snapshots. + /// Stream id within a channel for communications from the services to the consensus module. + /// + public const string CONSENSUS_MODULE_STREAM_ID_PROP_NAME = "aeron.cluster.consensus.module.stream.id"; + + /// + /// Default stream id within a channel for communications from the services to the consensus module. + /// + public const int CONSENSUS_MODULE_STREAM_ID_DEFAULT = 105; + + /// + /// Default channel to be used for archiving snapshots. /// public const string SNAPSHOT_CHANNEL_PROP_NAME = "aeron.cluster.snapshot.channel"; @@ -174,28 +184,27 @@ public class Configuration public const string SNAPSHOT_STREAM_ID_PROP_NAME = "aeron.cluster.snapshot.stream.id"; /// - /// Stream id for the archived snapshots within a channel. + /// Default stream id for the archived snapshots within a channel. /// - public const int SNAPSHOT_STREAM_ID_DEFAULT = 7; + public const int SNAPSHOT_STREAM_ID_DEFAULT = 106; /// - /// Directory to use for the clustered service. + /// Directory to use for the aeron cluster. /// - public const string CLUSTERED_SERVICE_DIR_PROP_NAME = "aeron.cluster.service.dir"; + public const string CLUSTER_DIR_PROP_NAME = "aeron.cluster.dir"; /// - /// Directory to use for the cluster container. + /// Default directory to use for the aeron cluster. /// - public const string CLUSTERED_SERVICE_DIR_DEFAULT = "clustered-service"; + public const string CLUSTER_DIR_DEFAULT = "aeron-cluster"; /// - /// Size in bytes of the error buffer for the cluster container. + /// Length in bytes of the error buffer for the cluster container. /// public const string ERROR_BUFFER_LENGTH_PROP_NAME = "aeron.cluster.service.error.buffer.length"; /// - /// Size in bytes of the error buffer for the cluster container. - /// Default to 1MB. + /// Default length in bytes of the error buffer for the cluster container. /// public const int ERROR_BUFFER_LENGTH_DEFAULT = 1024 * 1024; @@ -247,18 +256,29 @@ public static string ServiceControlChannel() { return Config.GetProperty(SERVICE_CONTROL_CHANNEL_PROP_NAME, SERVICE_CONTROL_CHANNEL_DEFAULT); } - + /// /// The value or system property - /// if set. + /// if set. /// /// or system property - /// if set. - public static int ServiceControlStreamId() + /// if set. + public static int ConsensusModuleStreamId() { - return Config.GetInteger(SERVICE_CONTROL_STREAM_ID_PROP_NAME, CONSENSUS_MODULE_STREAM_ID_DEFAULT); + return Config.GetInteger(CONSENSUS_MODULE_STREAM_ID_PROP_NAME, CONSENSUS_MODULE_STREAM_ID_DEFAULT); } + /// + /// The value or system property + /// if set. + /// + /// or system property + /// if set. + public static int ServiceStreamId() + { + return Config.GetInteger(SERVICE_STREAM_ID_PROP_NAME, SERVICE_CONTROL_STREAM_ID_DEFAULT); + } + /// /// The value or system property if set. /// @@ -296,14 +316,12 @@ public static Func IdleStrategySupplier(StatusIndicator controlla } /// - /// The value or system property - /// if set. + /// The value or system property if set. /// - /// or system property - /// if set. - public static string ClusteredServiceDirName() + /// or system property if set. + public static string ClusterDirName() { - return Config.GetProperty(CLUSTERED_SERVICE_DIR_PROP_NAME, CLUSTERED_SERVICE_DIR_DEFAULT); + return Config.GetProperty(CLUSTER_DIR_PROP_NAME, CLUSTER_DIR_DEFAULT); } /// @@ -324,12 +342,12 @@ public class Context : IDisposable private string replayChannel = Configuration.ReplayChannel(); private int replayStreamId = Configuration.ReplayStreamId(); private string serviceControlChannel = Configuration.ServiceControlChannel(); - private int serviceControlStreamId = Configuration.ServiceControlStreamId(); + private int consensusModuleStreamId = Configuration.ConsensusModuleStreamId(); + private int serviceStreamId = Configuration.ServiceStreamId(); private string snapshotChannel = Configuration.SnapshotChannel(); private int snapshotStreamId = Configuration.SnapshotStreamId(); private int errorBufferLength = Configuration.ErrorBufferLength(); - private bool deleteDirOnStart = false; - + private IThreadFactory threadFactory; private Func idleStrategySupplier; private IEpochClock epochClock; @@ -338,14 +356,13 @@ public class Context : IDisposable private AtomicCounter errorCounter; private CountedErrorHandler countedErrorHandler; private AeronArchive.Context archiveContext; - private string clusteredServiceDirectoryName = Configuration.ClusteredServiceDirName(); - private DirectoryInfo clusteredServiceDir; + private string clusteredServiceDirectoryName = Configuration.ClusterDirName(); + private DirectoryInfo clusterDir; private string aeronDirectoryName = Adaptive.Aeron.Aeron.Context.GetAeronDirectoryName(); private Aeron.Aeron aeron; private bool ownsAeronClient; private IClusteredService clusteredService; - private RecordingLog recordingLog; private ShutdownSignalBarrier shutdownSignalBarrier; private Action terminationHook; private ClusterMarkFile markFile; @@ -376,32 +393,20 @@ public void Conclude() epochClock = new SystemEpochClock(); } - if (deleteDirOnStart) - { - if (null != clusteredServiceDir) - { - IoUtil.Delete(clusteredServiceDir, true); - } - else - { - IoUtil.Delete(new DirectoryInfo(Configuration.ClusteredServiceDirName()), true); - } - } - - if (null == clusteredServiceDir) + if (null == clusterDir) { - clusteredServiceDir = new DirectoryInfo(clusteredServiceDirectoryName); + clusterDir = new DirectoryInfo(clusteredServiceDirectoryName); } - if (!clusteredServiceDir.Exists) + if (!clusterDir.Exists) { - Directory.CreateDirectory(clusteredServiceDir.FullName); + Directory.CreateDirectory(clusterDir.FullName); } if (null == markFile) { markFile = new ClusterMarkFile( - new FileInfo(Path.Combine(clusteredServiceDir.FullName, ClusterMarkFile.FILENAME)), + new FileInfo(Path.Combine(clusterDir.FullName, ClusterMarkFile.MarkFilenameForService(serviceId))), ClusterComponentType.CONTAINER, errorBufferLength, epochClock, @@ -426,18 +431,12 @@ public void Conclude() .ErrorHandler(errorHandler) .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"); + errorCounter = aeron.AddCounter(SYSTEM_COUNTER_TYPE_ID, "Cluster errors - service " + serviceId); } if (null == countedErrorHandler) @@ -462,11 +461,6 @@ public void Conclude() .OwnsAeronClient(false) .Lock(new NoOpLock()); - if (null == recordingLog) - { - recordingLog = new RecordingLog(clusteredServiceDir); - } - if (null == shutdownSignalBarrier) { shutdownSignalBarrier = new ShutdownSignalBarrier(); @@ -482,7 +476,7 @@ public void Conclude() 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"); + throw new ClusterException("either a ClusteredService instance or class name for the service must be provided"); } clusteredService = (IClusteredService) Activator.CreateInstance(Type.GetType(className)); @@ -603,27 +597,49 @@ public string ServiceControlChannel() } /// - /// Set the stream id for sending messages to the Consensus Module. + /// Set the stream id for communications from the consensus module and to the services. /// - /// for sending messages to the Consensus Module. + /// for communications from the consensus module and to the services. /// this for a fluent API - /// - public Context ServiceControlStreamId(int streamId) + /// + public Context ServiceStreamId(int streamId) { - serviceControlStreamId = streamId; + serviceStreamId = streamId; return this; } /// - /// Get the stream id for sending messages to the Consensus Module. + /// Get the stream id for communications from the consensus module and to the services. + /// + /// the stream id for communications from the consensus module and to the services. + /// + public int ServiceStreamId() + { + return serviceStreamId; + } + + /// + /// Set the stream id for communications from the services to the consensus module. /// - /// the stream id for sending messages to the Consensus Module. + /// for communications from the services to the consensus module. + /// this for a fluent API /// - public int ServiceControlStreamId() + public Context ConsensusModuleStreamId(int streamId) { - return serviceControlStreamId; + consensusModuleStreamId = streamId; + return this; } + /// + /// Get the stream id for communications from the services to the consensus module. + /// + /// the stream id for communications from the services to the consensus module. + /// + public int ConsensusModuleStreamId() + { + return consensusModuleStreamId; + } + /// /// Set the channel parameter for snapshot recordings. /// @@ -893,87 +909,47 @@ public AeronArchive.Context ArchiveContext() } /// - /// Should the container attempt to immediately delete on startup. - /// - /// Attempt deletion. - /// this for a fluent API. - public Context DeleteDirOnStart(bool deleteDirOnStart) - { - this.deleteDirOnStart = deleteDirOnStart; - return this; - } - - /// - /// Will the container attempt to immediately delete on startup. - /// - /// true when directory will be deleted, otherwise false. - public bool DeleteDirOnStart() - { - return deleteDirOnStart; - } - - /// - /// Set the directory name to use for the clustered service container. + /// Set the directory name to use for the consensus module directory.. /// - /// to use. + /// to use. /// this for a fluent API. - /// - public Context ClusteredServiceDirectoryName(string clusteredServiceDirectoryName) + /// + public Context ClusterDirectoryName(string clusterDirectoryName) { - this.clusteredServiceDirectoryName = clusteredServiceDirectoryName; + this.clusteredServiceDirectoryName = clusterDirectoryName; return this; } /// - /// The directory name used for the clustered service container. + /// The directory name to use for the cluster directory. /// - /// directory for the cluster container. - /// - public string ClusteredServiceDirectoryName() + /// directory name for the cluster directory. + /// + public string ClusterDirectoryName() { return clusteredServiceDirectoryName; } /// - /// Set the directory to use for the clustered service container. + /// Set the directory to use for the cluster directory. /// - /// to use. + /// to use. /// this for a fluent API. /// - public Context ClusteredServiceDir(DirectoryInfo dir) + public Context ClusterDir(DirectoryInfo clusterDir) { - this.clusteredServiceDir = dir; + this.clusterDir = clusterDir; return this; } /// - /// The directory used for the clustered service container. + /// The directory used for for the cluster directory. /// - /// directory for the cluster container. + /// directory for for the cluster directory. /// - public DirectoryInfo ClusteredServiceDir() - { - return clusteredServiceDir; - } - - /// - /// Set the for the log terms and snapshots. - /// - /// to use. - /// this for a fluent API. - public Context RecordingLog(RecordingLog recordingLog) - { - this.recordingLog = recordingLog; - return this; - } - - /// - /// The for the log terms and snapshots. - /// - /// for the log terms and snapshots. - public RecordingLog RecordingLog() + public DirectoryInfo ClusterDir() { - return recordingLog; + return clusterDir; } /// @@ -1087,9 +1063,9 @@ public DistinctErrorLog ErrorLog() /// public void DeleteDirectory() { - if (null != clusteredServiceDir) + if (null != clusterDir) { - IoUtil.Delete(clusteredServiceDir, false); + IoUtil.Delete(clusterDir, false); } } @@ -1123,9 +1099,10 @@ private void ConcludeMarkFile() encoder .ArchiveStreamId(archiveContext.ControlRequestStreamId()) - .ServiceControlStreamId(serviceControlStreamId) + .ServiceStreamId(serviceStreamId) + .ConsensusModuleStreamId(consensusModuleStreamId) .IngressStreamId(0) - .MemberId(-1) + .MemberId(Adaptive.Aeron.Aeron.NULL_VALUE) .ServiceId(serviceId) .AeronDirectory(aeron.Ctx().AeronDirectoryName()) .ArchiveChannel(archiveContext.ControlRequestChannel()) diff --git a/src/Adaptive.Cluster/Service/CommitPos.cs b/src/Adaptive.Cluster/Service/CommitPos.cs index 1e86d91a..98895db4 100644 --- a/src/Adaptive.Cluster/Service/CommitPos.cs +++ b/src/Adaptive.Cluster/Service/CommitPos.cs @@ -1,7 +1,8 @@ -using System; -using Adaptive.Aeron; +using Adaptive.Aeron; using Adaptive.Agrona; +using Adaptive.Agrona.Concurrent; using Adaptive.Agrona.Concurrent.Status; +using Adaptive.Cluster.Client; namespace Adaptive.Cluster.Service { @@ -17,14 +18,12 @@ namespace Adaptive.Cluster.Service /// | Recording ID for the leadership term | /// | | /// +---------------------------------------------------------------+ - /// | Log Position at base of leadership term | + /// | Log Position | /// | | /// +---------------------------------------------------------------+ - /// | Leadership Term ID | + /// | Max Log Position | /// | | /// +---------------------------------------------------------------+ - /// | Log Session ID | - /// +---------------------------------------------------------------+ /// /// public class CommitPos @@ -34,20 +33,15 @@ public class CommitPos /// public const int COMMIT_POSITION_TYPE_ID = 203; - /// - /// Represents a null value if the counter is not found. - /// - public const long NULL_VALUE = -1; - /// /// Human readable name for the counter. /// public const string NAME = "commit-pos: leadershipTermId="; - public static readonly int TERM_BASE_LOG_POSITION_OFFSET = 0; - public static readonly int LEADERSHIP_TERM_ID_OFFSET = TERM_BASE_LOG_POSITION_OFFSET + BitUtil.SIZE_OF_LONG; - public static readonly int LEADERSHIP_TERM_LENGTH_OFFSET = LEADERSHIP_TERM_ID_OFFSET + BitUtil.SIZE_OF_LONG; - public static readonly int KEY_LENGTH = LEADERSHIP_TERM_LENGTH_OFFSET + BitUtil.SIZE_OF_INT; + public static readonly int LEADERSHIP_TERM_ID_OFFSET = 0; + public static readonly int LOG_POSITION_OFFSET = LEADERSHIP_TERM_ID_OFFSET + BitUtil.SIZE_OF_LONG; + public static readonly int MAX_LOG_POSITION_OFFSET = LOG_POSITION_OFFSET + BitUtil.SIZE_OF_LONG; + public static readonly int KEY_LENGTH = MAX_LOG_POSITION_OFFSET + BitUtil.SIZE_OF_LONG; /// /// Allocate a counter to represent the commit position on stream for the current leadership term. @@ -55,19 +49,19 @@ public class CommitPos /// to allocate the counter. /// to use for building the key and label without allocation. /// of the log at the beginning of the leadership term. - /// of the log at the beginning of the leadership term. - /// length in bytes of the leadership term for the log. + /// of the log at the beginning of the leadership term. + /// length in bytes of the leadership term for the log. /// the for the commit position. public static Counter Allocate( Aeron.Aeron aeron, IMutableDirectBuffer tempBuffer, long leadershipTermId, - long termBaseLogPosition, - long leadershipTermLength) + long logPosition, + long maxLogPosition) { tempBuffer.PutLong(LEADERSHIP_TERM_ID_OFFSET, leadershipTermId); - tempBuffer.PutLong(TERM_BASE_LOG_POSITION_OFFSET, termBaseLogPosition); - tempBuffer.PutLong(LEADERSHIP_TERM_LENGTH_OFFSET, leadershipTermLength); + tempBuffer.PutLong(LOG_POSITION_OFFSET, logPosition); + tempBuffer.PutLong(MAX_LOG_POSITION_OFFSET, maxLogPosition); int labelOffset = 0; @@ -82,7 +76,7 @@ public static Counter Allocate( /// /// to search within. /// for the active commit position. - /// the leadership term id if found otherwise . + /// the leadership term id if found otherwise . public static long GetLeadershipTermId(CountersReader counters, int counterId) { IDirectBuffer buffer = counters.MetaDataBuffer; @@ -97,16 +91,16 @@ public static long GetLeadershipTermId(CountersReader counters, int counterId) } } - return NULL_VALUE; + return Aeron.Aeron.NULL_VALUE; } /// - /// Get the accumulated log position as a base for this leadership term. + /// Get the log position at which the commit tracking will begin. /// /// to search within. /// for the active commit position. - /// the base log position if found otherwise . - public static long GetTermBaseLogPosition(CountersReader counters, int counterId) + /// the base log position if found otherwise . + public static long GetLogPosition(CountersReader counters, int counterId) { IDirectBuffer buffer = counters.MetaDataBuffer; @@ -116,22 +110,22 @@ public static long GetTermBaseLogPosition(CountersReader counters, int counterId if (buffer.GetInt(recordOffset + CountersReader.TYPE_ID_OFFSET) == COMMIT_POSITION_TYPE_ID) { - return buffer.GetLong(recordOffset + CountersReader.KEY_OFFSET + TERM_BASE_LOG_POSITION_OFFSET); + return buffer.GetLong(recordOffset + CountersReader.KEY_OFFSET + LOG_POSITION_OFFSET); } } - return NULL_VALUE; + return Aeron.Aeron.NULL_VALUE; } /// - /// Get the length in bytes for the leadership term. + /// Get the maximum log position that a tracking session can reach. The get operation has volatile semantics. /// /// to search within. /// for the active commit position. - /// the base log position if found otherwise . - public static long GetLeadershipTermLength(CountersReader counters, int counterId) + /// the log position if found otherwise . + public static long GetMaxLogPosition(CountersReader counters, int counterId) { - IDirectBuffer buffer = counters.MetaDataBuffer; + IAtomicBuffer buffer = counters.MetaDataBuffer; if (counters.GetCounterState(counterId) == CountersReader.RECORD_ALLOCATED) { @@ -139,13 +133,39 @@ public static long GetLeadershipTermLength(CountersReader counters, int counterI if (buffer.GetInt(recordOffset + CountersReader.TYPE_ID_OFFSET) == COMMIT_POSITION_TYPE_ID) { - return buffer.GetLong(recordOffset + CountersReader.KEY_OFFSET + LEADERSHIP_TERM_LENGTH_OFFSET); + return buffer.GetLongVolatile(recordOffset + CountersReader.KEY_OFFSET + MAX_LOG_POSITION_OFFSET); } } - return NULL_VALUE; + return Aeron.Aeron.NULL_VALUE; } + /// + /// Set the maximum log position that a tracking session can reach. The set operation has volatile semantics. + /// + /// to search within. + /// for the active commit position. + /// to set for the new max position. + /// if the counter id is not valid. + public static void SetMaxLogPosition(CountersReader counters, int counterId, long value) + { + IAtomicBuffer buffer = counters.MetaDataBuffer; + + if (counters.GetCounterState(counterId) == CountersReader.RECORD_ALLOCATED) + { + int recordOffset = CountersReader.MetaDataOffset(counterId); + + if (buffer.GetInt(recordOffset + CountersReader.TYPE_ID_OFFSET) == COMMIT_POSITION_TYPE_ID) + { + buffer.PutLongVolatile(recordOffset + CountersReader.KEY_OFFSET + MAX_LOG_POSITION_OFFSET, value); + return; + } + } + + throw new ClusterException("Counter id not valid: " + counterId); + } + + /// /// Is the counter still active and log still recording? /// diff --git a/src/Adaptive.Cluster/Service/ServiceControlPublisher.cs b/src/Adaptive.Cluster/Service/ConsensusModuleProxy.cs similarity index 64% rename from src/Adaptive.Cluster/Service/ServiceControlPublisher.cs rename to src/Adaptive.Cluster/Service/ConsensusModuleProxy.cs index 77759188..73447f62 100644 --- a/src/Adaptive.Cluster/Service/ServiceControlPublisher.cs +++ b/src/Adaptive.Cluster/Service/ConsensusModuleProxy.cs @@ -1,11 +1,13 @@ using System; using Adaptive.Aeron; +using Adaptive.Aeron.Exceptions; using Adaptive.Aeron.LogBuffer; +using Adaptive.Cluster.Client; using Adaptive.Cluster.Codecs; namespace Adaptive.Cluster.Service { - internal class ServiceControlPublisher : IDisposable + internal class ConsensusModuleProxy : IDisposable { private const int SEND_ATTEMPTS = 3; @@ -13,12 +15,11 @@ internal class ServiceControlPublisher : IDisposable private readonly MessageHeaderEncoder _messageHeaderEncoder = new MessageHeaderEncoder(); private readonly ScheduleTimerEncoder _scheduleTimerEncoder = new ScheduleTimerEncoder(); private readonly CancelTimerEncoder _cancelTimerEncoder = new CancelTimerEncoder(); - private readonly ClusterActionAckEncoder _clusterActionAckEncoder = new ClusterActionAckEncoder(); - private readonly JoinLogEncoder _joinLogEncoder = new JoinLogEncoder(); + private readonly ServiceAckEncoder _serviceAckEncoder = new ServiceAckEncoder(); private readonly CloseSessionEncoder _closeSessionEncoder = new CloseSessionEncoder(); private readonly Publication _publication; - internal ServiceControlPublisher(Publication publication) + internal ConsensusModuleProxy(Publication publication) { _publication = publication; } @@ -28,6 +29,11 @@ public void Dispose() _publication?.Dispose(); } + public bool IsConnected() + { + return _publication.IsConnected; + } + public bool ScheduleTimer(long correlationId, long deadlineMs) { int length = MessageHeaderEncoder.ENCODED_LENGTH + ScheduleTimerEncoder.BLOCK_LENGTH; @@ -78,10 +84,15 @@ public bool CancelTimer(long correlationId) return false; } + + public void Ack(long logPosition, long ackId, int serviceId) + { + Ack(logPosition, ackId, Aeron.Aeron.NULL_VALUE, serviceId); + } - public void AckAction(long logPosition, long leadershipTermId, int serviceId, ClusterAction action) + public void Ack(long logPosition, long ackId, long relevantId, int serviceId) { - int length = MessageHeaderEncoder.ENCODED_LENGTH + ClusterActionAckEncoder.BLOCK_LENGTH; + int length = MessageHeaderEncoder.ENCODED_LENGTH + ServiceAckEncoder.BLOCK_LENGTH; int attempts = SEND_ATTEMPTS; do @@ -89,12 +100,12 @@ public void AckAction(long logPosition, long leadershipTermId, int serviceId, Cl long result = _publication.TryClaim(length, _bufferClaim); if (result > 0) { - _clusterActionAckEncoder + _serviceAckEncoder .WrapAndApplyHeader(_bufferClaim.Buffer, _bufferClaim.Offset, _messageHeaderEncoder) .LogPosition(logPosition) - .LeadershipTermId(leadershipTermId) - .ServiceId(serviceId) - .Action(action); + .AckId(ackId) + .RelevantId(relevantId) + .ServiceId(serviceId); _bufferClaim.Commit(); @@ -104,45 +115,9 @@ public void AckAction(long logPosition, long leadershipTermId, int serviceId, Cl CheckResult(result); } while (--attempts > 0); - throw new InvalidOperationException("failed to send ACK"); + throw new ClusterException("failed to send ACK"); } - - public void JoinLog( - long leadershipTermId, - int commitPositionId, - int logSessionId, - int logStreamId, - bool ackBeforeImage, - string channel) - { - int length = MessageHeaderEncoder.ENCODED_LENGTH + JoinLogEncoder.BLOCK_LENGTH + JoinLogEncoder.LogChannelHeaderLength() + channel.Length; - - int attempts = SEND_ATTEMPTS * 2; - do - { - long result = _publication.TryClaim(length, _bufferClaim); - if (result > 0) - { - _joinLogEncoder - .WrapAndApplyHeader(_bufferClaim.Buffer, _bufferClaim.Offset, _messageHeaderEncoder) - .LeadershipTermId(leadershipTermId) - .CommitPositionId(commitPositionId) - .LogSessionId(logSessionId) - .LogStreamId(logStreamId) - .AckBeforeImage(ackBeforeImage ? BooleanType.TRUE : BooleanType.FALSE) - .LogChannel(channel); - - _bufferClaim.Commit(); - - return; - } - - CheckResult(result); - } while (--attempts > 0); - - throw new InvalidOperationException("failed to send log connect request"); - } - + public bool CloseSession(long clusterSessionId) { int length = MessageHeaderEncoder.ENCODED_LENGTH + CloseSessionEncoder.BLOCK_LENGTH; @@ -172,7 +147,7 @@ private static void CheckResult(long result) { if (result == Publication.NOT_CONNECTED || result == Publication.CLOSED || result == Publication.MAX_POSITION_EXCEEDED) { - throw new InvalidOperationException("unexpected publication state: " + result); + throw new AeronException("unexpected publication state: " + result); } } } diff --git a/src/Adaptive.Cluster/Service/ICluster.cs b/src/Adaptive.Cluster/Service/ICluster.cs index 5f70921c..46265ee9 100644 --- a/src/Adaptive.Cluster/Service/ICluster.cs +++ b/src/Adaptive.Cluster/Service/ICluster.cs @@ -56,7 +56,7 @@ public interface ICluster /// /// /// to identify the timer when it expires. - /// after which the timer will fire. + /// Epoch time in milliseconds after which the timer will fire. /// true if the event to schedule a timer has been sent or false if back pressure is applied. /// bool ScheduleTimer(long correlationId, long deadlineMs); @@ -69,5 +69,10 @@ public interface ICluster /// bool CancelTimer(long correlationId); + /// + /// Should be called by the service when it experiences back pressure on egress, closing sessions, or making + /// timer requests. + /// + void Idle(); } } \ No newline at end of file diff --git a/src/Adaptive.Cluster/Service/IClusteredService.cs b/src/Adaptive.Cluster/Service/IClusteredService.cs index ce1e196d..2fa74c0e 100644 --- a/src/Adaptive.Cluster/Service/IClusteredService.cs +++ b/src/Adaptive.Cluster/Service/IClusteredService.cs @@ -37,14 +37,21 @@ public interface IClusteredService /// /// A message has been received to be processed by a clustered service. /// - /// identifying the client which sent the message. + /// for the client which sent the message. /// to associate any response. /// for when the message was received. /// containing the message. /// in the buffer at which the message is encoded. /// of the encoded message. /// aeron header for the incoming message. - void OnSessionMessage(long clusterSessionId, long correlationId, long timestampMs, IDirectBuffer buffer, int offset, int length, Header header); + void OnSessionMessage( + ClientSession session, + long correlationId, + long timestampMs, + IDirectBuffer buffer, + int offset, + int length, + Header header); /// /// A scheduled timer has expired. diff --git a/src/Adaptive.Cluster/Service/IServiceControlListener.cs b/src/Adaptive.Cluster/Service/IServiceControlListener.cs deleted file mode 100644 index 7bc3a2c6..00000000 --- a/src/Adaptive.Cluster/Service/IServiceControlListener.cs +++ /dev/null @@ -1,58 +0,0 @@ -using Adaptive.Cluster.Codecs; - -namespace Adaptive.Cluster.Service -{ - /// - /// Listens for events that can be bi-directional between the consensus module and services. - /// - /// The relevant handlers can be implemented and others ignored with the default implementations. - /// - /// - public interface IServiceControlListener - { - /// - /// Request from a service to schedule a timer. - /// - /// that must be unique across services for the timer. - /// after which the timer will expire and then fire. - void OnScheduleTimer(long correlationId, long deadline); - - /// - /// Request from a service to cancel a previously scheduled timer. - /// - /// of the previously scheduled timer. - void OnCancelTimer(long correlationId); - - /// - /// Acknowledgement from a service that it has undertaken the a requested . - /// - /// of the service after undertaking the action. - /// within which the action has taken place. - /// that has undertaken the action. - /// undertaken. - void OnServiceAck(long logPosition, long leadershipTermId, int serviceId, ClusterAction action); - - /// - /// Request that the services join to a log for replay or live stream. - /// - /// for the log. - /// for counter that gives the bound for consumption of the log. - /// for the log to confirm subscription. - /// to subscribe to for the log. - /// or after Image. - /// to subscribe to for the log. - void OnJoinLog( - long leadershipTermId, - int commitPositionId, - int logSessionId, - int logStreamId, - bool ackBeforeImage, - string logChannel); - - /// - /// Request that a cluster session be closed. - /// - /// of the session to be closed. - void OnServiceCloseSession(long clusterSessionId); - } -} \ No newline at end of file diff --git a/src/Adaptive.Cluster/Service/RecordingLog.cs b/src/Adaptive.Cluster/Service/RecordingLog.cs deleted file mode 100644 index 9c0e8b4b..00000000 --- a/src/Adaptive.Cluster/Service/RecordingLog.cs +++ /dev/null @@ -1,834 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using Adaptive.Agrona; -using Adaptive.Agrona.Concurrent; -using Adaptive.Archiver; -using Adaptive.Cluster.Codecs; - -namespace Adaptive.Cluster.Service -{ - /// - /// A log of recordings that make up the history of a Raft log. Entries are in order. - /// - /// The log is made up of entries of log terms or snapshots to roll up state as of a log position and leadership term. - /// - /// The latest state is made up of a the latest snapshot followed by any term logs which follow. It is possible that - /// the a snapshot is taken mid term and therefore the latest state is the snapshot plus the log of messages which - /// begin before the snapshot but continues after it. - /// - /// Record layout as follows: - /// - /// 0 1 2 3 - /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - /// | Recording ID | - /// | | - /// +---------------------------------------------------------------+ - /// | Leadership Term ID | - /// | | - /// +---------------------------------------------------------------+ - /// | Log Position at beginning of term | - /// | | - /// +---------------------------------------------------------------+ - /// | Term Position/Length | - /// | | - /// +---------------------------------------------------------------+ - /// | Timestamp at beginning of term or when snapshot was taken | - /// | | - /// +---------------------------------------------------------------+ - /// | Member ID vote | - /// +---------------------------------------------------------------+ - /// | Entry Type (Log or Snapshot) | - /// +---------------------------------------------------------------+ - /// | | - /// | ... - /// ... Repeats to the end of the log | - /// | | - /// +---------------------------------------------------------------+ - /// - /// - public class RecordingLog - { - /// - /// A copy of the entry in the log. - /// - public sealed class Entry - { - public readonly long recordingId; - public readonly long leadershipTermId; - public readonly long termBaseLogPosition; - public readonly long termPosition; - public readonly long timestamp; - public readonly int votedForMemberId; - public readonly int type; - public readonly int entryIndex; - - /// - /// A new entry in the recording log. - /// - /// of the entry in an archive. - /// of this entry. - /// accumulated position of the log over leadership terms for the beginning of the term. - /// position reached within the current leadership term, same at leadership term length. - /// of this entry. - /// which member this node voted for in the election. - /// of the entry as a log of a term or a snapshot. - /// of the entry on disk. - public Entry( - long recordingId, - long leadershipTermId, - long termBaseLogPosition, - long termPosition, - long timestamp, - int votedForMemberId, - int type, - int entryIndex) - { - this.recordingId = recordingId; - this.leadershipTermId = leadershipTermId; - this.termBaseLogPosition = termBaseLogPosition; - this.termPosition = termPosition; - this.timestamp = timestamp; - this.votedForMemberId = votedForMemberId; - this.type = type; - this.entryIndex = entryIndex; - } - - public Entry(RecoveryPlanDecoder.StepsDecoder decoder) - { - this.recordingId = decoder.RecordingId(); - this.leadershipTermId = decoder.LeadershipTermId(); - this.termBaseLogPosition = decoder.TermBaseLogPosition(); - this.termPosition = decoder.TermPosition(); - this.timestamp = decoder.Timestamp(); - this.votedForMemberId = decoder.VotedForMemberId(); - this.type = decoder.EntryType(); - this.entryIndex = decoder.EntryIndex(); - } - - - public void Encode(RecoveryPlanEncoder.StepsEncoder encoder) - { - encoder - .RecordingId(recordingId) - .LeadershipTermId(leadershipTermId) - .TermBaseLogPosition(termBaseLogPosition) - .TermPosition(termPosition) - .Timestamp(timestamp) - .VotedForMemberId(votedForMemberId) - .EntryType(type) - .EntryIndex(entryIndex); - } - - public override string ToString() - { - return "Entry{" + "recordingId=" + recordingId + - ", leadershipTermId=" + leadershipTermId + - ", termBaseLogPosition=" + termBaseLogPosition + - ", termPosition=" + termPosition + - ", timestamp=" + timestamp + - ", votedForMemberIdVote=" + votedForMemberId + - ", type=" + type + - ", entryIndex=" + entryIndex + - '}'; - } - } - - /// - /// Steps in a recovery plan. - /// - public class ReplayStep - { - public readonly long recordingStartPosition; - public readonly long recordingStopPosition; - public readonly int recordingSessionId; - public readonly Entry entry; - - public ReplayStep( - long recordingStartPosition, - long recordingStopPosition, - int recordingSessionId, - Entry entry) - { - this.recordingStartPosition = recordingStartPosition; - this.recordingStopPosition = recordingStopPosition; - this.recordingSessionId = recordingSessionId; - this.entry = entry; - } - - public ReplayStep(RecoveryPlanDecoder.StepsDecoder decoder) - { - recordingStartPosition = decoder.RecordingStartPosition(); - recordingStopPosition = decoder.RecordingStopPosition(); - recordingSessionId = decoder.RecordingSessionId(); - entry = new Entry(decoder); - } - - public void Encode(RecoveryPlanEncoder.StepsEncoder encoder) - { - encoder - .RecordingStartPosition(recordingStartPosition) - .RecordingStopPosition(recordingStopPosition) - .RecordingSessionId(recordingSessionId); - entry.Encode(encoder); - } - - public override string ToString() - { - return "ReplayStep{" + - "recordingStartPosition=" + recordingStartPosition + - ", recordingStopPosition=" + recordingStopPosition + - ", recordingSessionId=" + recordingSessionId + - ", entry=" + entry + - '}'; - } - } - - /// - /// The snapshot and steps to recover the state of a cluster. - /// - public class RecoveryPlan - { - public readonly long lastLeadershipTermId; - public readonly long lastTermBaseLogPosition; - public readonly long lastTermPositionCommitted; - public readonly long lastTermPositionAppended; - public readonly ReplayStep snapshotStep; - public readonly List termSteps; - public readonly RecoveryPlanEncoder encoder = new RecoveryPlanEncoder(); - public readonly RecoveryPlanDecoder decoder = new RecoveryPlanDecoder(); - - public RecoveryPlan( - long lastLeadershipTermId, - long lastTermBaseLogPosition, - long lastTermPositionCommitted, - long lastTermPositionAppended, - ReplayStep snapshotStep, - List termSteps) - { - this.lastLeadershipTermId = lastLeadershipTermId; - this.lastTermBaseLogPosition = lastTermBaseLogPosition; - this.lastTermPositionCommitted = lastTermPositionCommitted; - this.lastTermPositionAppended = lastTermPositionAppended; - this.snapshotStep = snapshotStep; - this.termSteps = termSteps; - } - - public RecoveryPlan(IDirectBuffer buffer, int offset) - { - decoder.Wrap(buffer, offset, RecoveryPlanDecoder.BLOCK_LENGTH, RecoveryPlanDecoder.SCHEMA_VERSION); - - lastLeadershipTermId = decoder.LastLeadershipTermId(); - lastTermBaseLogPosition = decoder.LastTermBaseLogPosition(); - lastTermPositionCommitted = decoder.LastTermPositionCommitted(); - lastTermPositionAppended = decoder.LastTermPositionAppended(); - - ReplayStep snapshot = null; - termSteps = new List(); - int stepNumber = 0; - - var stepDecoder = decoder.Steps(); - for (var i = 0; i < stepDecoder.Count(); i++) - { - if (0 == stepNumber && stepDecoder.EntryType() == ENTRY_TYPE_SNAPSHOT) - { - snapshot = new ReplayStep(stepDecoder); - } - else - { - termSteps.Add(new ReplayStep(stepDecoder)); - } - - stepNumber++; - stepDecoder = stepDecoder.Next(); - } - - snapshotStep = snapshot; - } - - public int EncodedLength() - { - int stepsCount = termSteps.Count + (null != snapshotStep ? 1 : 0); - - return RecoveryPlanEncoder.BLOCK_LENGTH + - RecoveryPlanEncoder.StepsEncoder.SbeHeaderSize() + - stepsCount * RecoveryPlanEncoder.StepsEncoder.SbeBlockLength(); - } - - public int Encode(IMutableDirectBuffer buffer, int offset) - { - encoder - .Wrap(buffer, offset) - .LastLeadershipTermId(lastLeadershipTermId) - .LastTermBaseLogPosition(lastTermBaseLogPosition) - .LastTermPositionCommitted(lastTermPositionCommitted) - .LastTermPositionAppended(lastTermPositionAppended); - - int stepsCount = termSteps.Count + (null != snapshotStep ? 1 : 0); - RecoveryPlanEncoder.StepsEncoder stepEncoder = encoder.StepsCount(stepsCount); - - if (null != snapshotStep) - { - stepEncoder.Next(); - snapshotStep.Encode(stepEncoder); - } - - for (int i = 0, size = termSteps.Count; i < size; i++) - { - stepEncoder.Next(); - termSteps[i].Encode(stepEncoder); - } - - return encoder.EncodedLength(); - } - - public override string ToString() - { - return "RecoveryPlan{" + - "lastLeadershipTermId=" + lastLeadershipTermId + - ", lastTermBaseLogPosition=" + lastTermBaseLogPosition + - ", lastTermPositionCommitted=" + lastTermPositionCommitted + - ", lastTermPositionAppended=" + lastTermPositionAppended + - ", snapshotStep=" + snapshotStep + - ", termSteps=" + termSteps + - '}'; - } - } - - /// - /// Filename for the recording index for the history of log terms and snapshots. - /// - public const string RECORDING_LOG_FILE_NAME = "recording.log"; - - /// - /// Represents a value that is not set or invalid. - /// - public const int NULL_VALUE = -1; - - /// - /// The log entry is for a recording of messages within a term to the consensus log. - /// - public const int ENTRY_TYPE_TERM = 0; - - /// - /// The log entry is for a recording of a snapshot of state taken as of a position in the log. - /// - public const int ENTRY_TYPE_SNAPSHOT = 1; - - /// - /// The offset at which the recording id for the entry is stored. - /// - public const int RECORDING_ID_OFFSET = 0; - - /// - /// The offset at which the leadership term id for the entry is stored. - /// - public static readonly int LEADERSHIP_TERM_ID_OFFSET = RECORDING_ID_OFFSET + BitUtil.SIZE_OF_LONG; - - /// - /// The offset at which the log position as of the beginning of the term for the entry is stored. - /// - public static readonly int TERM_BASE_LOG_POSITION_OFFSET = LEADERSHIP_TERM_ID_OFFSET + BitUtil.SIZE_OF_LONG; - - /// - /// The offset at which the term position is stored. - /// - public static readonly int TERM_POSITION_OFFSET = TERM_BASE_LOG_POSITION_OFFSET + BitUtil.SIZE_OF_LONG; - - /// - /// The offset at which the timestamp for the entry is stored. - /// - public static readonly int TIMESTAMP_OFFSET = TERM_POSITION_OFFSET + BitUtil.SIZE_OF_LONG; - - /// - /// The offset at which the voted for member id is recorded. - /// - public static readonly int MEMBER_ID_VOTE_OFFSET = TIMESTAMP_OFFSET + BitUtil.SIZE_OF_LONG; - - /// - /// The offset at which the type of the entry is stored. - /// - public static readonly int ENTRY_TYPE_OFFSET = MEMBER_ID_VOTE_OFFSET + BitUtil.SIZE_OF_INT; - - /// - /// The length of each entry. - /// - private static readonly int ENTRY_LENGTH = - BitUtil.Align(ENTRY_TYPE_OFFSET + BitUtil.SIZE_OF_INT, BitUtil.CACHE_LINE_LENGTH); - - private int nextEntryIndex; - private readonly DirectoryInfo parentDir; - private readonly FileInfo logFile; - private readonly byte[] byteBuffer = new byte[4096]; - private readonly UnsafeBuffer buffer; - private readonly List entries = new List(); - - /// - /// Create a log that appends to an existing log or creates a new one. - /// - /// in which the log will be created. - public RecordingLog(DirectoryInfo parentDir) - { - buffer = new UnsafeBuffer(byteBuffer); - - this.parentDir = parentDir; - logFile = new FileInfo(Path.Combine(parentDir.FullName, RECORDING_LOG_FILE_NAME)); - - Reload(); - } - - /// - /// List of currently loaded entries. - /// - /// the list of currently loaded entries. - public IList Entries() - { - return entries; - } - - /// - /// Get the next index to be used when appending an entry to the log. - /// - /// the next index to be used when appending an entry to the log. - public virtual int NextEntryIndex() - { - return nextEntryIndex; - } - - /// - /// Reload the log from disk. - /// - public void Reload() - { - entries.Clear(); - - FileStream fileChannel = null; - try - { - bool newFile = !logFile.Exists; - - fileChannel = new FileStream(logFile.FullName, FileMode.OpenOrCreate, FileAccess.ReadWrite, - FileShare.ReadWrite, 4096, FileOptions.WriteThrough); - - if (newFile) - { - SyncDirectory(parentDir); - return; - } - - // buffer clear - nextEntryIndex = 0; - while (true) - { - int length = fileChannel.Read(byteBuffer, 0, byteBuffer.Length); - if (length > 0) - { - CaptureEntriesFromBuffer(length, buffer, entries); - } - else - { - break; - } - } - } - finally - { - fileChannel?.Dispose(); - } - } - - /// - /// Get the latest snapshot in the log. - /// - /// the latest snapshot in the log or null if no snapshot exists. - public Entry GetLatestSnapshot() - { - for (int i = entries.Count - 1; i >= 0; i--) - { - Entry entry = entries[i]; - if (ENTRY_TYPE_SNAPSHOT == entry.type) - { - return entry; - } - } - - return null; - } - - /// - /// Create a recovery plan for the cluster that when the steps are replayed will bring the cluster back to the - /// latest stable state. - /// - /// to lookup recording descriptors. - /// a new for the cluster. - public virtual RecoveryPlan CreateRecoveryPlan(AeronArchive archive) - { - var steps = new List(); - - var snapshotStep = PlanRecovery(steps, entries, archive); - - long lastLeadershipTermId = -1; - long lastLogPosition = 0; - long lastTermPositionCommitted = -1; - long lastTermPositionAppended = 0; - - if (null != snapshotStep) - { - lastLeadershipTermId = snapshotStep.entry.leadershipTermId; - lastLogPosition = snapshotStep.entry.termBaseLogPosition; - lastTermPositionCommitted = snapshotStep.entry.termPosition; - lastTermPositionAppended = lastTermPositionCommitted; - } - - int size = steps.Count; - if (size > 0) - { - ReplayStep replayStep = steps[size - 1]; - Entry entry = replayStep.entry; - - lastLeadershipTermId = entry.leadershipTermId; - lastLogPosition = entry.termBaseLogPosition; - lastTermPositionCommitted = entry.termPosition; - lastTermPositionAppended = replayStep.recordingStopPosition; - } - - return new RecoveryPlan(lastLeadershipTermId, lastLogPosition, lastTermPositionCommitted, lastTermPositionAppended, snapshotStep, steps); - } - - /// - /// Get the latest snapshot for a given position within a leadership term. - /// - /// in which the snapshot was taken. - /// within the leadership term. - /// the latest snapshot for a given position or null if no match found. - public Entry GetSnapshot(long leadershipTermId, long termPosition) - { - for (int i = entries.Count - 1; i >= 0; i--) - { - Entry entry = entries[i]; - if (entry.type == ENTRY_TYPE_SNAPSHOT && leadershipTermId == entry.leadershipTermId && termPosition == entry.termPosition) - { - return entry; - } - } - - return null; - } - - - /// - /// Append a log entry for a Raft term. - /// - /// for the current term. - /// reached at the beginning of the term. - /// at the beginning of the term. - /// in the leader election. - public void AppendTerm(long leadershipTermId, long logPosition, long timestamp, int votedForMemberId) - { - int size = entries.Count; - if (size > 0) - { - long expectedTermId = leadershipTermId - 1; - Entry entry = entries[size - 1]; - - if (entry.type != NULL_VALUE && entry.leadershipTermId != expectedTermId) - { - throw new InvalidOperationException("leadershipTermId out of sequence: previous " + entry.leadershipTermId + " this " + leadershipTermId); - } - } - - Append(ENTRY_TYPE_TERM, NULL_VALUE, leadershipTermId, logPosition, AeronArchive.NULL_POSITION, timestamp, votedForMemberId); - } - - /// - /// Append a log entry for a snapshot. - /// - /// in the archive for the snapshot. - /// for the current term - /// at the beginning of the leadership term. - /// for the position in the current term or length so far for that term. - /// at which the snapshot was taken. - public void AppendSnapshot(long recordingId, long leadershipTermId, long logPosition, long termPosition, long timestamp) - { - int size = entries.Count; - if (size > 0) - { - Entry entry = entries[size - 1]; - - if (entry.type == ENTRY_TYPE_TERM && entry.leadershipTermId != leadershipTermId) - { - throw new InvalidOperationException("leadershipTermId out of sequence: previous " + entry.leadershipTermId + " this " + leadershipTermId); - } - } - - Append(ENTRY_TYPE_SNAPSHOT, recordingId, leadershipTermId, logPosition, termPosition, timestamp, NULL_VALUE); - } - - /// - /// Commit the recording id of the log for a leadership term. - /// - /// for committing the recording id for the log. - /// for the log of the leadership term. - public void CommitLeadershipRecordingId(long leadershipTermId, long recordingId) - { - int index = GetLeadershipTermEntryIndex(leadershipTermId); - - CommitEntryValue(index, recordingId, RECORDING_ID_OFFSET); - - Entry entry = entries[index]; - entries[index] = new Entry( - recordingId, - entry.leadershipTermId, - entry.termBaseLogPosition, - entry.termPosition, - entry.timestamp, - entry.votedForMemberId, - entry.type, - entry.entryIndex); - } - - /// - /// Commit the position reached in a leadership term before a clean shutdown. - /// - /// for committing the term position reached. - /// reached in the leadership term. - public void CommitLeadershipTermPosition(long leadershipTermId, long termPosition) - { - int index = GetLeadershipTermEntryIndex(leadershipTermId); - - CommitEntryValue(index, termPosition, TERM_POSITION_OFFSET); - - Entry entry = entries[index]; - entries[index] = new Entry( - entry.recordingId, - entry.leadershipTermId, - entry.termBaseLogPosition, - termPosition, - entry.timestamp, - entry.votedForMemberId, - entry.type, - entry.entryIndex); - } - - /// - /// Commit the position for the base of a leadership term. - /// - /// for committing the base position.. - /// for the base of a leadership term. - public void CommitLeadershipLogPosition(long leadershipTermId, long logPosition) - { - int index = GetLeadershipTermEntryIndex(leadershipTermId); - - CommitEntryValue(index, logPosition, TERM_BASE_LOG_POSITION_OFFSET); - - Entry entry = entries[index]; - entries[index] = new Entry( - entry.recordingId, - entry.leadershipTermId, - logPosition, - entry.termPosition, - entry.timestamp, - entry.votedForMemberId, - entry.type, - entry.entryIndex); - } - - /// - /// Tombstone an entry in the log so it is no longer valid. - /// - /// to match for validation. - /// reached in the leadership term. - public void TombstoneEntry(long leadershipTermId, int entryIndex) - { - int index = -1; - for (int i = 0, size = entries.Count; i < size; i++) - { - Entry entry = entries[i]; - if (entry.leadershipTermId == leadershipTermId && entry.entryIndex == entryIndex) - { - index = entry.entryIndex; - break; - } - } - - if (-1 == index) - { - throw new ArgumentException("unknown entry index: " + entryIndex); - } - - buffer.PutInt(0, NULL_VALUE, ByteOrder.LittleEndian); - long filePosition = (index * ENTRY_LENGTH) + ENTRY_TYPE_OFFSET; - - using (var fileChannel = new FileStream(logFile.FullName, FileMode.Append, FileAccess.Write, - FileShare.ReadWrite, BitUtil.SIZE_OF_INT, FileOptions.WriteThrough)) - { - fileChannel.Position = filePosition; - fileChannel.Write(byteBuffer, 0, BitUtil.SIZE_OF_INT); // Check - } - } - - public override string ToString() - { - return "RecodingLog{" + - "file=" + logFile.FullName + - ", entries=" + entries + - '}'; - } - - private void Append(int entryType, long recordingId, long leadershipTermId, long logPosition, long termPosition, long timestamp, int votedForMemberId) - { - buffer.PutLong(RECORDING_ID_OFFSET, recordingId, ByteOrder.LittleEndian); - buffer.PutLong(TERM_BASE_LOG_POSITION_OFFSET, logPosition, ByteOrder.LittleEndian); - buffer.PutLong(LEADERSHIP_TERM_ID_OFFSET, leadershipTermId, ByteOrder.LittleEndian); - buffer.PutLong(TIMESTAMP_OFFSET, timestamp, ByteOrder.LittleEndian); - buffer.PutLong(TERM_POSITION_OFFSET, termPosition, ByteOrder.LittleEndian); - buffer.PutInt(MEMBER_ID_VOTE_OFFSET, votedForMemberId, ByteOrder.LittleEndian); - buffer.PutInt(ENTRY_TYPE_OFFSET, entryType, ByteOrder.LittleEndian); - - using (var fileChannel = new FileStream(logFile.FullName, FileMode.Append, FileAccess.Write, - FileShare.ReadWrite, 4096, FileOptions.WriteThrough)) - { - fileChannel.Write(byteBuffer, 0, ENTRY_LENGTH); - } - - entries.Add(new Entry(recordingId, leadershipTermId, logPosition, AeronArchive.NULL_POSITION, timestamp, votedForMemberId, entryType, nextEntryIndex++)); - } - - private void CaptureEntriesFromBuffer(int limit, UnsafeBuffer buffer, List entries) - { - for (int i = 0, length = limit; i < length; i += ENTRY_LENGTH) - { - int entryType = buffer.GetInt(i + ENTRY_TYPE_OFFSET); - - if (NULL_VALUE != entryType) - { - entries.Add(new Entry( - buffer.GetLong(i + RECORDING_ID_OFFSET, ByteOrder.LittleEndian), - buffer.GetLong(i + LEADERSHIP_TERM_ID_OFFSET, ByteOrder.LittleEndian), - buffer.GetLong(i + TERM_BASE_LOG_POSITION_OFFSET, ByteOrder.LittleEndian), - buffer.GetLong(i + TERM_POSITION_OFFSET, ByteOrder.LittleEndian), - buffer.GetLong(i + TIMESTAMP_OFFSET, ByteOrder.LittleEndian), - buffer.GetInt(i + MEMBER_ID_VOTE_OFFSET, ByteOrder.LittleEndian), - entryType, - nextEntryIndex)); - } - - ++nextEntryIndex; - } - } - - private static void SyncDirectory(DirectoryInfo dir) - { - try - { - dir.Refresh(); // No ideal whether this is doing the correct thing - } - catch (Exception) - { - } - } - - private static void GetRecordingExtent(AeronArchive archive, RecordingExtent recordingExtent, Entry entry) - { - if (archive.ListRecording(entry.recordingId, recordingExtent) == 0) - { - throw new InvalidOperationException("unknown recording id: " + entry.recordingId); - } - } - - private int GetLeadershipTermEntryIndex(long leadershipTermId) - { - for (int i = 0, size = entries.Count; i < size; i++) - { - Entry entry = entries[i]; - if (entry.leadershipTermId == leadershipTermId && entry.type == ENTRY_TYPE_TERM) - { - return entry.entryIndex; - } - } - - throw new ArgumentException("unknown leadershipTermId: " + leadershipTermId); - } - - private static ReplayStep PlanRecovery(List steps, List entries, AeronArchive archive) - { - if (entries.Count == 0) - { - return null; - } - - int snapshotIndex = -1; - for (int i = entries.Count - 1; i >= 0; i--) - { - Entry entry = entries[i]; - if (ENTRY_TYPE_SNAPSHOT == entry.type) - { - snapshotIndex = i; - break; - } - } - - ReplayStep snapshotStep; - RecordingExtent recordingExtent = new RecordingExtent(); - - if (-1 != snapshotIndex) - { - Entry snapshot = entries[snapshotIndex]; - GetRecordingExtent(archive, recordingExtent, snapshot); - - snapshotStep = new ReplayStep( - recordingExtent.startPosition, recordingExtent.stopPosition, recordingExtent.sessionId, snapshot); - - if (snapshotIndex - 1 >= 0) - { - for (int i = snapshotIndex - 1; i >= 0; i--) - { - Entry entry = entries[i]; - if (ENTRY_TYPE_TERM == entry.type) - { - GetRecordingExtent(archive, recordingExtent, entry); - long snapshotPosition = snapshot.termBaseLogPosition + snapshot.termPosition; - - if (recordingExtent.stopPosition == AeronArchive.NULL_POSITION || - (entry.termBaseLogPosition + recordingExtent.stopPosition) > snapshotPosition) - { - steps.Add(new ReplayStep( - snapshot.termPosition, recordingExtent.stopPosition, recordingExtent.sessionId, entry)); - } - - break; - } - } - } - } - else - { - snapshotStep = null; - } - - for (int i = snapshotIndex + 1, length = entries.Count; i < length; i++) - { - Entry entry = entries[i]; - GetRecordingExtent(archive, recordingExtent, entry); - - steps.Add(new ReplayStep(recordingExtent.startPosition, recordingExtent.stopPosition, recordingExtent.sessionId, entry)); - } - - return snapshotStep; - } - - private void CommitEntryValue(long entryIndex, long value, int fieldOffset) - { - buffer.PutLong(0, value, ByteOrder.LittleEndian); - long filePosition = (entryIndex * ENTRY_LENGTH) + fieldOffset; - - using (var fileChannel = new FileStream(logFile.FullName, FileMode.Append, FileAccess.Write, - FileShare.ReadWrite, BitUtil.SIZE_OF_LONG, FileOptions.WriteThrough)) - { - fileChannel.Position = filePosition; - fileChannel.Write(byteBuffer, 0, BitUtil.SIZE_OF_LONG); // Check - } - } - } -} \ No newline at end of file diff --git a/src/Adaptive.Cluster/Service/RecoveryState.cs b/src/Adaptive.Cluster/Service/RecoveryState.cs index bc8493be..1d5d41c3 100644 --- a/src/Adaptive.Cluster/Service/RecoveryState.cs +++ b/src/Adaptive.Cluster/Service/RecoveryState.cs @@ -1,6 +1,7 @@ using Adaptive.Aeron; using Adaptive.Agrona; using Adaptive.Agrona.Concurrent.Status; +using Adaptive.Cluster.Client; namespace Adaptive.Cluster.Service { @@ -15,13 +16,21 @@ namespace Adaptive.Cluster.Service /// | Leadership Term ID | /// | | /// +---------------------------------------------------------------+ - /// | Term position for snapshot | + /// | Log position for Snapshot | /// | | /// +---------------------------------------------------------------+ - /// | Timestamp at beginning of recovery | + /// | Timestamp at beginning of Recovery | /// | | /// +---------------------------------------------------------------+ - /// | Count of leadership replay terms | + /// | Replay required flag | + /// +---------------------------------------------------------------+ + /// | Count of Services | + /// +---------------------------------------------------------------+ + /// | Snapshot Recording ID (Service ID 0) | + /// | | + /// +---------------------------------------------------------------+ + /// | Snapshot Recording ID (Service ID n) | + /// | | /// +---------------------------------------------------------------+ /// /// @@ -32,48 +41,69 @@ public class RecoveryState /// public const int RECOVERY_STATE_TYPE_ID = 204; - /// - /// Represents a null value if the counter is not found. - /// - public const int NULL_VALUE = -1; - /// /// Human readable name for the counter. /// public const string NAME = "cluster recovery: leadershipTermId="; public const int LEADERSHIP_TERM_ID_OFFSET = 0; - public static readonly int TERM_POSITION_OFFSET = LEADERSHIP_TERM_ID_OFFSET + BitUtil.SIZE_OF_LONG; - public static readonly int TIMESTAMP_OFFSET = TERM_POSITION_OFFSET + BitUtil.SIZE_OF_LONG; - public static readonly int REPLAY_TERM_COUNT_OFFSET = TIMESTAMP_OFFSET + BitUtil.SIZE_OF_LONG; - public static readonly int KEY_LENGTH = REPLAY_TERM_COUNT_OFFSET + BitUtil.SIZE_OF_INT; + public static readonly int LOG_POSITION_OFFSET = LEADERSHIP_TERM_ID_OFFSET + BitUtil.SIZE_OF_LONG; + public static readonly int TIMESTAMP_OFFSET = LOG_POSITION_OFFSET + BitUtil.SIZE_OF_LONG; + public static readonly int REPLAY_FLAG_OFFSET = TIMESTAMP_OFFSET + BitUtil.SIZE_OF_LONG; + public static readonly int SERVICE_COUNT_OFFSET = REPLAY_FLAG_OFFSET + BitUtil.SIZE_OF_INT; + public static readonly int SNAPSHOT_RECORDING_IDS_OFFSET = SERVICE_COUNT_OFFSET + BitUtil.SIZE_OF_INT; + /// /// Allocate a counter to represent the snapshot services should load on start. /// - /// to allocate the counter. - /// to use for building the key and label without allocation. - /// at which the snapshot was taken. - /// at which the snapshot was taken. - /// the snapshot was taken. - /// for the count of terms to be replayed during recovery after snapshot. - /// the for the consensus position. - public static Counter Allocate(Aeron.Aeron aeron, IMutableDirectBuffer tempBuffer, long termPosition, long leadershipTermId, long timestamp, int replayTermCount) + /// to allocate the counter. + /// to use for building the key and label without allocation. + /// at which the snapshot was taken. + /// at which the snapshot was taken. + /// the snapshot was taken. + /// flag is true if all or part of the log must be replayed. + /// for the services to use during recovery indexed by service id. + /// the for the recovery state. + 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(TERM_POSITION_OFFSET, termPosition); + tempBuffer.PutLong(LOG_POSITION_OFFSET, logPosition); tempBuffer.PutLong(TIMESTAMP_OFFSET, timestamp); - tempBuffer.PutInt(REPLAY_TERM_COUNT_OFFSET, replayTermCount); + 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(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); + 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); } /// @@ -102,11 +132,11 @@ public static int FindCounterId(CountersReader counters) } /// - /// Get the leadership term id for the recovery state. + /// Get the leadership term id for the snapshot state. if no snapshot for recovery. /// /// to search within. /// for the active consensus position. - /// the message index if found otherwise . + /// the leadership term id if found otherwise . public static long GetLeadershipTermId(CountersReader counters, int counterId) { IDirectBuffer buffer = counters.MetaDataBuffer; @@ -121,16 +151,16 @@ public static long GetLeadershipTermId(CountersReader counters, int counterId) } } - return NULL_VALUE; + return Aeron.Aeron.NULL_VALUE; } - + /// - /// Get the term position for recovery within the leadership term. + /// Get the position at which the snapshot was taken. if no snapshot for recovery. /// /// to search within. /// for the active consensus position. - /// the log position if found otherwise . - public static long GetTermPosition(CountersReader counters, int counterId) + /// the log position if found otherwise . + public static long GetLogPosition(CountersReader counters, int counterId) { IDirectBuffer buffer = counters.MetaDataBuffer; @@ -140,20 +170,20 @@ public static long GetTermPosition(CountersReader counters, int counterId) if (buffer.GetInt(recordOffset + CountersReader.TYPE_ID_OFFSET) == RECOVERY_STATE_TYPE_ID) { - return buffer.GetLong(recordOffset + CountersReader.KEY_OFFSET + TERM_POSITION_OFFSET); + return buffer.GetLong(recordOffset + CountersReader.KEY_OFFSET + LOG_POSITION_OFFSET); } } - return NULL_VALUE; + return Aeron.Aeron.NULL_VALUE; } /// - /// Get the timestamp at the beginning of recovery. + /// Get the timestamp at the beginning of recovery. if no snapshot for recovery. /// /// to search within. /// for the active recovery counter. - /// the timestamp if found otherwise . + /// the timestamp if found otherwise . public static long GetTimestamp(CountersReader counters, int counterId) { IDirectBuffer buffer = counters.MetaDataBuffer; @@ -168,16 +198,16 @@ public static long GetTimestamp(CountersReader counters, int counterId) } } - return NULL_VALUE; + return Aeron.Aeron.NULL_VALUE; } /// - /// Get the count of terms that will be replayed during recovery. + /// Has the recovery process got a log to replay? /// /// to search within. /// for the active recovery counter. - /// the count of replay terms if found otherwise . - public static int GetReplayTermCount(CountersReader counters, int counterId) + /// true if a replay is required. + public static bool HasReplay(CountersReader counters, int counterId) { IDirectBuffer buffer = counters.MetaDataBuffer; @@ -187,11 +217,41 @@ public static int GetReplayTermCount(CountersReader counters, int counterId) if (buffer.GetInt(recordOffset + CountersReader.TYPE_ID_OFFSET) == RECOVERY_STATE_TYPE_ID) { - return buffer.GetInt(recordOffset + CountersReader.KEY_OFFSET + REPLAY_TERM_COUNT_OFFSET); + return buffer.GetInt(recordOffset + CountersReader.KEY_OFFSET + REPLAY_FLAG_OFFSET) == 1; + } + } + + return false; + } + + /// + /// Get the recording id of the snapshot for a service. + /// + /// to search within. + /// for the active recovery counter. + /// for the snapshot required. + /// the count of replay terms if found otherwise . + public static long GetSnapshotRecordingId(CountersReader counters, int counterId, int serviceId) + { + IDirectBuffer buffer = counters.MetaDataBuffer; + + if (counters.GetCounterState(counterId) == CountersReader.RECORD_ALLOCATED) + { + int recordOffset = CountersReader.MetaDataOffset(counterId); + + if (buffer.GetInt(recordOffset + CountersReader.TYPE_ID_OFFSET) == RECOVERY_STATE_TYPE_ID) + { + int serviceCount = buffer.GetInt(recordOffset + CountersReader.KEY_OFFSET + SERVICE_COUNT_OFFSET); + if (serviceId < 0 || serviceId >= serviceCount) + { + throw new ClusterException("invalid serviceId " + serviceId + " for count of " + serviceCount); + } + + return buffer.GetLong(recordOffset + CountersReader.KEY_OFFSET + SNAPSHOT_RECORDING_IDS_OFFSET + (serviceId * BitUtil.SIZE_OF_LONG)); } } - return NULL_VALUE; + throw new ClusterException("Active counter not found " + counterId); } } } \ No newline at end of file diff --git a/src/Adaptive.Cluster/Service/ServiceAdapter.cs b/src/Adaptive.Cluster/Service/ServiceAdapter.cs new file mode 100644 index 00000000..27e6d7c1 --- /dev/null +++ b/src/Adaptive.Cluster/Service/ServiceAdapter.cs @@ -0,0 +1,59 @@ +using System; +using Adaptive.Aeron; +using Adaptive.Aeron.LogBuffer; +using Adaptive.Agrona; +using Adaptive.Cluster.Client; +using Adaptive.Cluster.Codecs; + +namespace Adaptive.Cluster.Service +{ + sealed class ServiceAdapter : IFragmentHandler, IDisposable + { + private readonly Subscription subscription; + private readonly ClusteredServiceAgent clusteredServiceAgent; + + private readonly MessageHeaderDecoder messageHeaderDecoder = new MessageHeaderDecoder(); + private readonly JoinLogDecoder joinLogDecoder = new JoinLogDecoder(); + + public ServiceAdapter(Subscription subscription, ClusteredServiceAgent clusteredServiceAgent) + { + this.subscription = subscription; + this.clusteredServiceAgent = clusteredServiceAgent; + } + + public void Dispose() + { + subscription?.Dispose(); + } + + public int Poll() + { + return subscription.Poll(this, 1); + } + + public void OnFragment(IDirectBuffer buffer, int offset, int length, Header header) + { + messageHeaderDecoder.Wrap(buffer, offset); + + int templateId = messageHeaderDecoder.TemplateId(); + + if (JoinLogDecoder.TEMPLATE_ID != templateId) + { + throw new ClusterException("unknown template id: " + templateId); + } + + joinLogDecoder.Wrap( + buffer, + offset + MessageHeaderDecoder.ENCODED_LENGTH, + messageHeaderDecoder.BlockLength(), + messageHeaderDecoder.Version()); + + clusteredServiceAgent.OnJoinLog( + joinLogDecoder.LeadershipTermId(), + joinLogDecoder.CommitPositionId(), + joinLogDecoder.LogSessionId(), + joinLogDecoder.LogStreamId(), + joinLogDecoder.LogChannel()); + } + } +} \ No newline at end of file diff --git a/src/Adaptive.Cluster/Service/ServiceControlAdapter.cs b/src/Adaptive.Cluster/Service/ServiceControlAdapter.cs deleted file mode 100644 index 93d95e0a..00000000 --- a/src/Adaptive.Cluster/Service/ServiceControlAdapter.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using Adaptive.Aeron; -using Adaptive.Aeron.LogBuffer; -using Adaptive.Agrona; -using Adaptive.Cluster.Codecs; - -namespace Adaptive.Cluster.Service -{ - public sealed class ServiceControlAdapter : IFragmentHandler, IDisposable - { - internal readonly Subscription subscription; - internal readonly IServiceControlListener serviceControlListener; - - private readonly MessageHeaderDecoder messageHeaderDecoder = new MessageHeaderDecoder(); - private readonly ScheduleTimerDecoder scheduleTimerDecoder = new ScheduleTimerDecoder(); - private readonly CancelTimerDecoder cancelTimerDecoder = new CancelTimerDecoder(); - private readonly ClusterActionAckDecoder clusterActionAckDecoder = new ClusterActionAckDecoder(); - private readonly JoinLogDecoder joinLogDecoder = new JoinLogDecoder(); - private readonly CloseSessionDecoder closeSessionDecoder = new CloseSessionDecoder(); - - public ServiceControlAdapter(Subscription subscription, IServiceControlListener serviceControlListener) - { - this.subscription = subscription; - this.serviceControlListener = serviceControlListener; - } - - public void Dispose() - { - subscription?.Dispose(); - } - - public int Poll() - { - return subscription.Poll(this, 1); - } - - public void OnFragment(IDirectBuffer buffer, int offset, int length, Header header) - { - messageHeaderDecoder.Wrap(buffer, offset); - - int templateId = messageHeaderDecoder.TemplateId(); - switch (templateId) - { - case ScheduleTimerDecoder.TEMPLATE_ID: - scheduleTimerDecoder.Wrap(buffer, offset + MessageHeaderDecoder.ENCODED_LENGTH, - messageHeaderDecoder.BlockLength(), messageHeaderDecoder.Version()); - - serviceControlListener.OnScheduleTimer(scheduleTimerDecoder.CorrelationId(), - scheduleTimerDecoder.Deadline()); - break; - - case CancelTimerDecoder.TEMPLATE_ID: - cancelTimerDecoder.Wrap(buffer, offset + MessageHeaderDecoder.ENCODED_LENGTH, - messageHeaderDecoder.BlockLength(), messageHeaderDecoder.Version()); - - serviceControlListener.OnCancelTimer(scheduleTimerDecoder.CorrelationId()); - break; - - case ClusterActionAckDecoder.TEMPLATE_ID: - clusterActionAckDecoder.Wrap(buffer, offset + MessageHeaderDecoder.ENCODED_LENGTH, - messageHeaderDecoder.BlockLength(), messageHeaderDecoder.Version()); - - serviceControlListener.OnServiceAck(clusterActionAckDecoder.LogPosition(), - clusterActionAckDecoder.LeadershipTermId(), clusterActionAckDecoder.ServiceId(), - clusterActionAckDecoder.Action()); - break; - - case JoinLogDecoder.TEMPLATE_ID: - joinLogDecoder.Wrap(buffer, offset + MessageHeaderDecoder.ENCODED_LENGTH, - messageHeaderDecoder.BlockLength(), messageHeaderDecoder.Version()); - - serviceControlListener.OnJoinLog( - joinLogDecoder.LeadershipTermId(), - joinLogDecoder.CommitPositionId(), - joinLogDecoder.LogSessionId(), - joinLogDecoder.LogStreamId(), - joinLogDecoder.AckBeforeImage() == BooleanType.TRUE, - joinLogDecoder.LogChannel()); - break; - - case CloseSessionDecoder.TEMPLATE_ID: - closeSessionDecoder.Wrap( - buffer, - offset + MessageHeaderDecoder.ENCODED_LENGTH, - messageHeaderDecoder.BlockLength(), - messageHeaderDecoder.Version()); - - serviceControlListener.OnServiceCloseSession(closeSessionDecoder.ClusterSessionId()); - break; - - default: - throw new ArgumentException("unknown template id: " + templateId); - } - } - } -} \ No newline at end of file diff --git a/src/Adaptive.Cluster/Service/ServiceSnapshotLoader.cs b/src/Adaptive.Cluster/Service/ServiceSnapshotLoader.cs index 49e096ef..f23463f8 100644 --- a/src/Adaptive.Cluster/Service/ServiceSnapshotLoader.cs +++ b/src/Adaptive.Cluster/Service/ServiceSnapshotLoader.cs @@ -2,6 +2,7 @@ using Adaptive.Aeron; using Adaptive.Aeron.LogBuffer; using Adaptive.Agrona; +using Adaptive.Cluster.Client; using Adaptive.Cluster.Codecs; namespace Adaptive.Cluster.Service @@ -42,12 +43,16 @@ public ControlledFragmentHandlerAction OnFragment(IDirectBuffer buffer, int offs switch (templateId) { case SnapshotMarkerDecoder.TEMPLATE_ID: - snapshotMarkerDecoder.Wrap(buffer, offset + MessageHeaderDecoder.ENCODED_LENGTH, messageHeaderDecoder.BlockLength(), messageHeaderDecoder.Version()); + snapshotMarkerDecoder.Wrap( + buffer, + offset + MessageHeaderDecoder.ENCODED_LENGTH, + messageHeaderDecoder.BlockLength(), + messageHeaderDecoder.Version()); long typeId = snapshotMarkerDecoder.TypeId(); if (typeId != ClusteredServiceContainer.SNAPSHOT_TYPE_ID) { - throw new InvalidOperationException("unexpected snapshot type: " + typeId); + throw new ClusterException("unexpected snapshot type: " + typeId); } switch (snapshotMarkerDecoder.Mark()) @@ -55,7 +60,7 @@ public ControlledFragmentHandlerAction OnFragment(IDirectBuffer buffer, int offs case SnapshotMark.BEGIN: if (inSnapshot) { - throw new InvalidOperationException("already in snapshot"); + throw new ClusterException("already in snapshot"); } inSnapshot = true; @@ -64,7 +69,7 @@ public ControlledFragmentHandlerAction OnFragment(IDirectBuffer buffer, int offs case SnapshotMark.END: if (!inSnapshot) { - throw new InvalidOperationException("missing begin snapshot"); + throw new ClusterException("missing begin snapshot"); } isDone = true; @@ -75,9 +80,9 @@ public ControlledFragmentHandlerAction OnFragment(IDirectBuffer buffer, int offs case ClientSessionDecoder.TEMPLATE_ID: clientSessionDecoder.Wrap( - buffer, - offset + MessageHeaderDecoder.ENCODED_LENGTH, - messageHeaderDecoder.BlockLength(), + buffer, + offset + MessageHeaderDecoder.ENCODED_LENGTH, + messageHeaderDecoder.BlockLength(), messageHeaderDecoder.Version()); string responseChannel = clientSessionDecoder.ResponseChannel(); @@ -85,14 +90,15 @@ public ControlledFragmentHandlerAction OnFragment(IDirectBuffer buffer, int offs clientSessionDecoder.GetEncodedPrincipal(encodedPrincipal, 0, encodedPrincipal.Length); agent.AddSession( - clientSessionDecoder.ClusterSessionId(), - clientSessionDecoder.ResponseStreamId(), - responseChannel, + clientSessionDecoder.ClusterSessionId(), + clientSessionDecoder.LastCorrelationId(), + clientSessionDecoder.ResponseStreamId(), + responseChannel, encodedPrincipal); break; default: - throw new InvalidOperationException("unknown template id: " + templateId); + throw new ClusterException("unknown template id: " + templateId); } return ControlledFragmentHandlerAction.CONTINUE; diff --git a/src/Adaptive.Cluster/Service/ServiceSnapshotTaker.cs b/src/Adaptive.Cluster/Service/ServiceSnapshotTaker.cs index 3329d870..c3264e85 100644 --- a/src/Adaptive.Cluster/Service/ServiceSnapshotTaker.cs +++ b/src/Adaptive.Cluster/Service/ServiceSnapshotTaker.cs @@ -29,6 +29,7 @@ public void SnapshotSession(ClientSession session) { _clientSessionEncoder.WrapAndApplyHeader(bufferClaim.Buffer, bufferClaim.Offset, messageHeaderEncoder) .ClusterSessionId(session.Id()) + .LastCorrelationId(session.LastCorrelationId()) .ResponseStreamId(session.ResponseStreamId()) .ResponseChannel(responseChannel) .PutEncodedPrincipal(encodedPrincipal, 0, encodedPrincipal.Length); diff --git a/src/Adaptive.Cluster/Service/SnapshotTaker.cs b/src/Adaptive.Cluster/Service/SnapshotTaker.cs index d1883c2b..72c433c0 100644 --- a/src/Adaptive.Cluster/Service/SnapshotTaker.cs +++ b/src/Adaptive.Cluster/Service/SnapshotTaker.cs @@ -1,5 +1,6 @@ using System.Threading; using Adaptive.Aeron; +using Adaptive.Aeron.Exceptions; using Adaptive.Aeron.LogBuffer; using Adaptive.Agrona.Concurrent; using Adaptive.Cluster.Codecs; @@ -41,7 +42,12 @@ public void MarkSnapshot(long snapshotTypeId, long logPosition, long leadershipT long result = publication.TryClaim(ENCODED_MARKER_LENGTH, bufferClaim); if (result > 0) { - snapshotMarkerEncoder.WrapAndApplyHeader(bufferClaim.Buffer, bufferClaim.Offset, messageHeaderEncoder).TypeId(snapshotTypeId).LogPosition(logPosition).LeadershipTermId(leadershipTermId).Index(snapshotIndex).Mark(snapshotMark); + snapshotMarkerEncoder.WrapAndApplyHeader(bufferClaim.Buffer, bufferClaim.Offset, messageHeaderEncoder) + .TypeId(snapshotTypeId) + .LogPosition(logPosition) + .LeadershipTermId(leadershipTermId) + .Index(snapshotIndex) + .Mark(snapshotMark); bufferClaim.Commit(); break; @@ -67,7 +73,7 @@ protected static void CheckResult(long result) { if (result == Publication.NOT_CONNECTED || result == Publication.CLOSED || result == Publication.MAX_POSITION_EXCEEDED) { - throw new System.InvalidOperationException("unexpected publication state: " + result); + throw new AeronException("unexpected publication state: " + result); } } @@ -81,10 +87,7 @@ protected void CheckResultAndIdle(long result) protected void InvokeAeronClient() { - if (null != aeronClientInvoker) - { - aeronClientInvoker.Invoke(); - } + aeronClientInvoker?.Invoke(); } } } \ No newline at end of file diff --git a/src/Adaptive.Cluster/aeron-cluster-codecs.xml b/src/Adaptive.Cluster/aeron-cluster-codecs.xml index 1bf3ec31..7f8733b9 100644 --- a/src/Adaptive.Cluster/aeron-cluster-codecs.xml +++ b/src/Adaptive.Cluster/aeron-cluster-codecs.xml @@ -41,14 +41,11 @@ 2 - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 + 0 + 1 + 2 + 3 + 4 0 @@ -112,21 +109,31 @@ --> - + + + + + + - + - + @@ -135,14 +142,6 @@ - - - - - - @@ -160,12 +159,8 @@ id="6" description="Event to indicate a new leader has been elected for the cluster"> - - - - - - + + - + + + + + + + + + - + + + + - + - - - + + + + id="40" + description="Consensus Module instructing a service to join a log"> - - - - - - + + + - - + + - - - - - + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -365,16 +437,17 @@ id="102" description="A serialised client session in the context of a service"> - - - + + + + + description="A serialised client session in the context of a Consensus Module"> - + @@ -389,32 +462,10 @@ - + description="Serialised state of the Consensus Module"> - - - - - - - - - - - - - - - - - - - - diff --git a/src/Adaptive.Cluster/aeron-cluster-mark-codecs.xml b/src/Adaptive.Cluster/aeron-cluster-mark-codecs.xml index 425a65e1..95248699 100644 --- a/src/Adaptive.Cluster/aeron-cluster-mark-codecs.xml +++ b/src/Adaptive.Cluster/aeron-cluster-mark-codecs.xml @@ -35,24 +35,26 @@ id="200" blockLength="128" description="Header of Consensus Module and Container Mark file"> - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + +