private byte[] EncodeOffsetRequest(OffsetRequest request) { var message = new WriteByteStream(); if (request.Offsets == null) { request.Offsets = new List <Offset>(); } message.Pack(EncodeHeader(request)); var topicGroups = request.Offsets.GroupBy(x => x.Topic).ToList(); message.Pack(ReplicaId.ToBytes(), topicGroups.Count.ToBytes()); foreach (var topicGroup in topicGroups) { var partitions = topicGroup.GroupBy(x => x.PartitionId).ToList(); message.Pack(topicGroup.Key.ToInt16SizedBytes(), partitions.Count.ToBytes()); foreach (var partition in partitions) { foreach (var offset in partition) { message.Pack(partition.Key.ToBytes(), offset.Time.ToBytes(), offset.MaxOffsets.ToBytes()); } } } message.Prepend(message.Length().ToBytes()); return(message.Payload()); }
public JsonRow(string streamId, ReplicaId replicaId, VClock timestamp, string jsonPayload) { StreamId = streamId; ReplicaId = replicaId; Timestamp = timestamp; JsonPayload = jsonPayload; }
/// <inheritdoc /> public Task <ReplicaInfo> GetReplicaInfoAsync( PartitionId partitionId, ReplicaId replicaId, long?serverTimeout = 60, CancellationToken cancellationToken = default(CancellationToken)) { partitionId.ThrowIfNull(nameof(partitionId)); replicaId.ThrowIfNull(nameof(replicaId)); serverTimeout?.ThrowIfOutOfInclusiveRange("serverTimeout", 1, 4294967295); var requestId = Guid.NewGuid().ToString(); var url = "Partitions/{partitionId}/$/GetReplicas/{replicaId}"; url = url.Replace("{partitionId}", partitionId.ToString()); url = url.Replace("{replicaId}", replicaId.ToString()); var queryParams = new List <string>(); // Append to queryParams if not null. serverTimeout?.AddToQueryParameters(queryParams, $"timeout={serverTimeout}"); queryParams.Add("api-version=6.0"); url += "?" + string.Join("&", queryParams); HttpRequestMessage RequestFunc() { var request = new HttpRequestMessage() { Method = HttpMethod.Get, }; return(request); } return(this.httpClient.SendAsyncGetResponse(RequestFunc, url, ReplicaInfoConverter.Deserialize, requestId, cancellationToken)); }
public PayloadRow(string streamId, ReplicaId replicaId, VClock timestamp, int serializerId, byte[] payload) { StreamId = streamId; ReplicaId = replicaId; Timestamp = timestamp; SerializerId = serializerId; Payload = payload; }
void OnPossessPawn(BitStream bs) { var replicaId = bs.ReadReplicaId(); var pawnIdx = bs.ReadByte(); currentReplicaPossess = replicaId; pawnIdxToPossess = pawnIdx; }
/// <summary> /// Increments a logical time value for a target <paramref name="replicaId"/>, /// returning new instance of <see cref="VClock"/> in the result. /// </summary> public VClock Increment(ReplicaId replicaId) { long time; return(Value != null && Value.TryGetValue(replicaId, out time) ? new VClock(Value.SetItem(replicaId, time + 1)) : new VClock((Value ?? ImmutableDictionary <ReplicaId, long> .Empty).SetItem(replicaId, 1L))); }
/// <summary> /// Returns a new instance of the <see cref="VClock"/> containing /// only information about target <paramref name="replicaId"/>. /// </summary> public VClock CopyOne(ReplicaId replicaId) { long time; return(Value != null && Value.TryGetValue(replicaId, out time) ? new VClock(ImmutableDictionary.CreateRange(new[] { new KeyValuePair <ReplicaId, long>(replicaId, time) })) : new VClock(ImmutableDictionary <ReplicaId, long> .Empty)); }
public PendingAck(ReplicaId target, Versioned <T> versioned, DateTime timestamp, ImmutableHashSet <ReplicaId> members) { Target = target; Versioned = versioned; Timestamp = timestamp; Members = members; hashCode = HashCode(); }
void OnDisconnected(string reason) { Debug.Log("[Client] <b>Disconnected</b> (" + reason + ")"); // Cleanup currentReplicaPossess = ReplicaId.Invalid; Client.replicaManager.Reset(); if (sceneHandle.IsValid()) { Addressables.UnloadSceneAsync(sceneHandle); } }
public override int GetHashCode() { int hash = 1; if (ReplicaId.Length != 0) { hash ^= ReplicaId.GetHashCode(); } if (Result != 0) { hash ^= Result.GetHashCode(); } return(hash); }
/// <inheritdoc /> public Task <ReplicaHealth> GetReplicaHealthUsingPolicyAsync( PartitionId partitionId, ReplicaId replicaId, int?eventsHealthStateFilter = 0, ApplicationHealthPolicy applicationHealthPolicy = default(ApplicationHealthPolicy), long?serverTimeout = 60, CancellationToken cancellationToken = default(CancellationToken)) { partitionId.ThrowIfNull(nameof(partitionId)); replicaId.ThrowIfNull(nameof(replicaId)); serverTimeout?.ThrowIfOutOfInclusiveRange("serverTimeout", 1, 4294967295); var requestId = Guid.NewGuid().ToString(); var url = "Partitions/{partitionId}/$/GetReplicas/{replicaId}/$/GetHealth"; url = url.Replace("{partitionId}", partitionId.ToString()); url = url.Replace("{replicaId}", replicaId.ToString()); var queryParams = new List <string>(); // Append to queryParams if not null. eventsHealthStateFilter?.AddToQueryParameters(queryParams, $"EventsHealthStateFilter={eventsHealthStateFilter}"); serverTimeout?.AddToQueryParameters(queryParams, $"timeout={serverTimeout}"); queryParams.Add("api-version=6.0"); url += "?" + string.Join("&", queryParams); string content; using (var sw = new StringWriter()) { if (applicationHealthPolicy != default(ApplicationHealthPolicy)) { ApplicationHealthPolicyConverter.Serialize(new JsonTextWriter(sw), applicationHealthPolicy); } content = sw.ToString(); } HttpRequestMessage RequestFunc() { var request = new HttpRequestMessage() { Method = HttpMethod.Post, Content = new StringContent(content, Encoding.UTF8), }; request.Content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json; charset=utf-8"); return(request); } return(this.httpClient.SendAsyncGetResponse(RequestFunc, url, ReplicaHealthConverter.Deserialize, requestId, cancellationToken)); }
/// <inheritdoc /> public Task ReportReplicaHealthAsync( PartitionId partitionId, ReplicaId replicaId, ReplicaHealthReportServiceKind?replicaHealthReportServiceKind, HealthInformation healthInformation, bool?immediate = false, long?serverTimeout = 60, CancellationToken cancellationToken = default(CancellationToken)) { partitionId.ThrowIfNull(nameof(partitionId)); replicaId.ThrowIfNull(nameof(replicaId)); replicaHealthReportServiceKind.ThrowIfNull(nameof(replicaHealthReportServiceKind)); healthInformation.ThrowIfNull(nameof(healthInformation)); serverTimeout?.ThrowIfOutOfInclusiveRange("serverTimeout", 1, 4294967295); var requestId = Guid.NewGuid().ToString(); var url = "Partitions/{partitionId}/$/GetReplicas/{replicaId}/$/ReportHealth"; url = url.Replace("{partitionId}", partitionId.ToString()); url = url.Replace("{replicaId}", replicaId.ToString()); var queryParams = new List <string>(); // Append to queryParams if not null. replicaHealthReportServiceKind?.AddToQueryParameters(queryParams, $"ReplicaHealthReportServiceKind={replicaHealthReportServiceKind.ToString()}"); immediate?.AddToQueryParameters(queryParams, $"Immediate={immediate}"); serverTimeout?.AddToQueryParameters(queryParams, $"timeout={serverTimeout}"); queryParams.Add("api-version=6.0"); url += "?" + string.Join("&", queryParams); string content; using (var sw = new StringWriter()) { HealthInformationConverter.Serialize(new JsonTextWriter(sw), healthInformation); content = sw.ToString(); } HttpRequestMessage RequestFunc() { var request = new HttpRequestMessage() { Method = HttpMethod.Post, Content = new StringContent(content, Encoding.UTF8), }; request.Content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json; charset=utf-8"); return(request); } return(this.httpClient.SendAsync(RequestFunc, url, requestId, cancellationToken)); }
/// <inheritdoc /> public Task <IEnumerable <ReplicaEvent> > GetPartitionReplicaEventListAsync( PartitionId partitionId, ReplicaId replicaId, string startTimeUtc, string endTimeUtc, long?serverTimeout = 60, string eventsTypesFilter = default(string), bool?excludeAnalysisEvents = default(bool?), bool?skipCorrelationLookup = default(bool?), CancellationToken cancellationToken = default(CancellationToken)) { partitionId.ThrowIfNull(nameof(partitionId)); replicaId.ThrowIfNull(nameof(replicaId)); startTimeUtc.ThrowIfNull(nameof(startTimeUtc)); endTimeUtc.ThrowIfNull(nameof(endTimeUtc)); serverTimeout?.ThrowIfOutOfInclusiveRange("serverTimeout", 1, 4294967295); var requestId = Guid.NewGuid().ToString(); var url = "EventsStore/Partitions/{partitionId}/$/Replicas/{replicaId}/$/Events"; url = url.Replace("{partitionId}", partitionId.ToString()); url = url.Replace("{replicaId}", replicaId.ToString()); var queryParams = new List <string>(); // Append to queryParams if not null. serverTimeout?.AddToQueryParameters(queryParams, $"timeout={serverTimeout}"); startTimeUtc?.AddToQueryParameters(queryParams, $"StartTimeUtc={startTimeUtc}"); endTimeUtc?.AddToQueryParameters(queryParams, $"EndTimeUtc={endTimeUtc}"); eventsTypesFilter?.AddToQueryParameters(queryParams, $"EventsTypesFilter={eventsTypesFilter}"); excludeAnalysisEvents?.AddToQueryParameters(queryParams, $"ExcludeAnalysisEvents={excludeAnalysisEvents}"); skipCorrelationLookup?.AddToQueryParameters(queryParams, $"SkipCorrelationLookup={skipCorrelationLookup}"); queryParams.Add("api-version=6.4"); url += "?" + string.Join("&", queryParams); HttpRequestMessage RequestFunc() { var request = new HttpRequestMessage() { Method = HttpMethod.Get, }; return(request); } return(this.httpClient.SendAsyncGetResponseAsList(RequestFunc, url, ReplicaEventConverter.Deserialize, requestId, cancellationToken)); }
/// <inheritdoc /> public Task RemoveReplicaAsync( NodeName nodeName, PartitionId partitionId, ReplicaId replicaId, bool?forceRemove = default(bool?), long?serverTimeout = 60, CancellationToken cancellationToken = default(CancellationToken)) { nodeName.ThrowIfNull(nameof(nodeName)); partitionId.ThrowIfNull(nameof(partitionId)); replicaId.ThrowIfNull(nameof(replicaId)); serverTimeout?.ThrowIfOutOfInclusiveRange("serverTimeout", 1, 4294967295); var requestId = Guid.NewGuid().ToString(); var url = "Nodes/{nodeName}/$/GetPartitions/{partitionId}/$/GetReplicas/{replicaId}/$/Delete"; url = url.Replace("{nodeName}", Uri.EscapeDataString(nodeName.ToString())); url = url.Replace("{partitionId}", partitionId.ToString()); url = url.Replace("{replicaId}", replicaId.ToString()); var queryParams = new List <string>(); // Append to queryParams if not null. forceRemove?.AddToQueryParameters(queryParams, $"ForceRemove={forceRemove}"); serverTimeout?.AddToQueryParameters(queryParams, $"timeout={serverTimeout}"); queryParams.Add("api-version=6.0"); url += "?" + string.Join("&", queryParams); HttpRequestMessage RequestFunc() { var request = new HttpRequestMessage() { Method = HttpMethod.Post, }; return(request); } return(this.httpClient.SendAsync(RequestFunc, url, requestId, cancellationToken)); }
public void TestStatic() { // Setup var masterSystem = CreateSystem(); var master = masterSystem.CreateStreamWriter(); var slaveSystem = CreateSystem(); bool slaveReplicaAdded = false; slaveSystem.ReplicaAdded += x => slaveReplicaAdded = true; // Add ReplicaId id = 10; masterSystem.AddStaticReplica(id, new Protobuf.TestObject() { Name = "A" }, StaticReplicaOptions.DefaultMaster); slaveSystem.AddStaticReplica(id, new Protobuf.TestObject() { Name = "A" }, StaticReplicaOptions.DefaultSlave); slaveReplicaAdded = false; master.WriteTo(slaveSystem); Assert.IsFalse(slaveReplicaAdded); // Update masterSystem.UpdateReplica(id, new Protobuf.TestObject() { State = 2 }); master.WriteTo(slaveSystem); Assert.AreEqual(slaveSystem.GetReplica <Protobuf.TestObject>(id).State, 2); }
public VClock SetTime(ReplicaId replicaId, long localTime) => new VClock((Value ?? ImmutableDictionary <ReplicaId, long> .Empty).SetItem(replicaId, localTime));
/// <summary> /// Creates a new instance of a <see cref="VClock"/> with <paramref name="value"/> set for target replica. /// </summary> public static VClock Create(ReplicaId replicaId, long value = 1L) => new VClock(new KeyValuePair <ReplicaId, long>(replicaId, value));
public Send(ReplicaId origin, ReplicaId lastSeenBy, Versioned <T> versioned) { Origin = origin; LastSeenBy = lastSeenBy; Versioned = versioned; }
public ReplicatorActor(ReplicaId myself, ReplicatorSettings settings) { this.myself = myself; this.settings = settings; replicatorRelativePath = Self.Path.ToStringWithoutAddress(); Receive <ClusterEvent.MemberUp>(up => { if (HasRole(up.Member) && up.Member.Address != cluster.SelfAddress) { // send invitation to a new member var path = up.Member.Address.ToString() + replicatorRelativePath; Context.ActorSelection(path).Tell(new Invitation(myself, Self)); } }); Receive <ClusterEvent.IMemberEvent>(_ => { /* ignore */ }); Receive <Broadcast <T> >(bcast => { var version = localVersion.Increment(myself); var versioned = new Versioned <T>(version, bcast.Message); var send = new Send <T>(myself, myself, versioned); if (log.IsInfoEnabled) { log.Info("Sending {0} to: {1}", send, string.Join(", ", members)); } foreach (var member in members) { member.Value.Forward(send); } var pendingAck = new PendingAck <T>(myself, versioned, DateTime.UtcNow, members.Keys.ToImmutableHashSet()); this.pendingAcks = pendingAcks.Add(pendingAck); this.localVersion = version; }); Receive <Send <T> >(send => { if (AlreadySeen(send.Versioned.Version)) { log.Info("Received duplicate message {0}", send); } else { var receivers = members.Remove(send.Origin); var forward = send.WithLastSeenBy(myself); if (log.IsInfoEnabled) { log.Info("Broadcasting message {0} to: {1}", forward, string.Join(", ", receivers.Values)); } foreach (var member in receivers.Values) { member.Forward(forward); } if (members.TryGetValue(send.LastSeenBy, out var sender)) { sender.Tell(new SendAck(myself, send.Versioned.Version), ActorRefs.NoSender); } var deliver = new Deliver <T>(send.Origin, send.Versioned); Self.Forward(deliver); this.pendingDelivery = pendingDelivery.Add(deliver); this.pendingAcks = pendingAcks.Add(new PendingAck <T>(myself, send.Versioned, DateTime.UtcNow, receivers.Keys.ToImmutableHashSet())); } }); Receive <SendAck>(ack => { log.Info("Received ACK from {0} (version: {1})", Sender, ack.Version); var pendingAck = this.pendingAcks.First(x => x.Versioned.Version == ack.Version); var membersLeft = pendingAck.Members.Remove(ack.ReplicaId); this.pendingAcks = pendingAcks.Remove(pendingAck); if (!membersLeft.IsEmpty) { this.pendingAcks = pendingAcks.Add(pendingAck.WithMembers(membersLeft)); } }); Receive <Deliver <T> >(deliver => { TryToCasuallyDeliver(deliver); remoteVersions = remoteVersions.SetItem(deliver.Origin, deliver.Versioned.Version); latestStableVersion = UpdateStableVersion(remoteVersions); }); Receive <Resend>(_ => { var now = DateTime.UtcNow; var builder = pendingAcks.ToBuilder(); foreach (var ack in pendingAcks) { if (now - ack.Timestamp > settings.RetryTimeout) { builder.Remove(ack); var send = new Send <T>(myself, myself, ack.Versioned); foreach (var replicaId in ack.Members) { if (members.TryGetValue(replicaId, out var member)) { member.Tell(send, ActorRefs.NoSender); } } builder.Add(ack.WithTimestamp(now)); } } pendingAcks = builder.ToImmutable(); }); Receive <Invitation>(invitation => { log.Info("Received invitation from {0} (ID: {1})", invitation.ReplicatorRef, invitation.ReplicaId); members = members.Add(invitation.ReplicaId, invitation.ReplicatorRef); Context.Watch(invitation.ReplicatorRef); }); Receive <StableReq>(sync => { var reply = sync.Versions.Where(ver => latestStableVersion >= ver).ToArray(); Sender.Tell(new StableRep(reply)); }); Receive <Subscribe <T> >(subscribe => { subscribers = subscribers.Add(subscribe.Ref); if (subscribe.Ack != null) { subscribe.Ref.Tell(subscribe.Ack); } }); Receive <Unsubscribe>(unsubscribe => { subscribers = subscribers.Remove(unsubscribe.Ref); if (unsubscribe.Ack != null) { unsubscribe.Ref.Tell(unsubscribe.Ack); } }); Receive <Terminated>(terminated => { subscribers = subscribers.Remove(terminated.ActorRef); var replicaId = members.FirstOrDefault(kv => Equals(kv.Value, terminated.ActorRef)); members = members.Remove(replicaId.Key); }); resendTask = Context.System.Scheduler .ScheduleTellOnceCancelable(settings.ResendInterval, Self, Resend.Instance, ActorRefs.NoSender); }
public SendAck(ReplicaId replicaId, VClock version) { ReplicaId = replicaId; Version = version; }
public Send <T> WithLastSeenBy(ReplicaId lastSender) => new Send <T>(Origin, lastSender, Versioned);
/// <summary> /// Serializes the object to JSON. /// </summary> /// <param name="writer">The <see cref="T: Newtonsoft.Json.JsonWriter" /> to write to.</param> /// <param name="value">The object to serialize to JSON.</param> public static void Serialize(JsonWriter writer, ReplicaId value) { writer.WriteValue(value.ToString()); }
public Deliver(ReplicaId origin, Versioned <T> versioned) { Origin = origin; Versioned = versioned; }
public Invitation(ReplicaId replicaId, IActorRef replicatorRef) { ReplicaId = replicaId; ReplicatorRef = replicatorRef; }
public Position(int id, int replicaId) { Id = id; ReplicaId = replicaId; }
/// <summary> /// Returns a local time value for target <paramref name="replicaId"/> /// stored in current <see cref="VClock"/>. /// </summary> public long this[ReplicaId replicaId] => Value?.GetValueOrDefault(replicaId, 0L) ?? 0L;