public override void OnWireReceived(UnsafeReader reader) //endpoint's side { var taskId = RdId.Read(reader); var wiredTask = new WiredRdTask <TReq, TRes> .Endpoint(myBindLifetime, this, taskId, myCancellationScheduler ?? SynchronousScheduler.Instance); //subscribe for lifetime cancellation var externalCancellation = wiredTask.Lifetime; using (UsingDebugInfo()) //now supports only sync handlers { RdTask <TRes> rdTask; try { var value = ReadRequestDelegate(SerializationContext, reader); ReceiveTrace?.Log($"{wiredTask} :: received request: {value.PrintToString()}"); var handler = Handler; if (handler == null) { var message = $"Handler is not set for {wiredTask} :: received request: {value.PrintToString()}"; ourLogReceived.Error(message); rdTask = RdTask <TRes> .Faulted(new Exception(message)); } else { try { rdTask = handler(externalCancellation, value); } catch (Exception ex) { rdTask = RdTask <TRes> .Faulted(ex); } } } catch (Exception e) { rdTask = RdTask <TRes> .Faulted(new Exception($"Unexpected exception in {wiredTask}", e)); } rdTask.Result.Advise(Lifetime.Eternal, result => { try { if (result.Status == RdTaskStatus.Success) { AssertNullability(result.Result); } wiredTask.ResultInternal.SetIfEmpty(result); } catch (Exception ee) { ourLogSend.Error($"Problem when responding to `{wiredTask}`", ee); wiredTask.Set(new RdFault(ee)); } }); } }
public override void OnWireReceived(UnsafeReader reader) { var value = myReadValue(SerializationContext, reader); ReceiveTrace?.Log($"{this} :: value = {value.PrintToString()}"); using (UsingDebugInfo()) mySignal.Fire(value); }
public override void OnWireReceived(UnsafeReader reader) //endpoint's side { var taskId = RdId.Read(reader); var wiredTask = new WiredRdTask <TReq, TRes>(this, taskId, myEndpointSchedulerForHandlerAndCancellation ?? WireScheduler, true); //subscribe for lifetime cancellation var externalCancellation = wiredTask.Subscribe(myBindLifetime); using (UsingDebugInfo()) //now supports only sync handlers { RdTask <TRes> rdTask; try { var value = ReadRequestDelegate(SerializationContext, reader); ReceiveTrace?.Log($"{wiredTask} :: received request: {value.PrintToString()}"); rdTask = Handler(externalCancellation, value); } catch (Exception e) { rdTask = RdTask <TRes> .Faulted(e); } rdTask.Result.Advise(Lifetime.Eternal, result => { try { if (result.Status == RdTaskStatus.Success) { AssertNullability(result.Result); } wiredTask.ResultInternal.SetIfEmpty(result); } catch (Exception ee) { ourLogSend.Error($"Problem when responding to `{wiredTask}`", ee); wiredTask.Set(new RdFault(ee)); } }); } }
public override void OnWireReceived(UnsafeReader reader) { var version = reader.ReadInt(); var value = ReadValueDelegate(SerializationContext, reader); var rejected = IsMaster && version < myMasterVersion; ReceiveTrace?.Log($"{this} :: oldver = {myMasterVersion}, newver = {version}, value = {value.PrintToString()}{(rejected ? " REJECTED" : "")}"); if (rejected) { return; } myMasterVersion = version; using (UsingDebugInfo()) { myProperty.Value = value; } }
public override void OnWireReceived(UnsafeReader reader) { var remoteState = (ExtState)reader.ReadInt(); ReceiveTrace?.Log($"Ext {Location} ({RdId}) : {remoteState}"); switch (remoteState) { case ExtState.Ready: SendState(myExtWire.RealWire, ExtState.ReceivedCounterPart); myExtWire.Connected.Set(true); break; case ExtState.ReceivedCounterPart: myExtWire.Connected.Set(true); //don't set anything if already set break; case ExtState.Disconnected: myExtWire.Connected.Set(false); break; default: throw new ArgumentOutOfRangeException("Unsupported state: " + remoteState); } var counterpartSerializationHash = reader.ReadLong(); if (counterpartSerializationHash != SerializationHash) { base.Proto.Scheduler.Queue(() => { base.Proto.OutOfSyncModels.Add(this); }); if (base.Proto is Protocol p && p.ThrowErrorOnOutOfSyncModels) { Assertion.Fail($"{this} : SerializationHash doesn't match to counterpart: maybe you forgot to generate models?" + $"Our: `${SerializationHash}` counterpart: {counterpartSerializationHash}"); } } }
public override void OnWireReceived(UnsafeReader stream) { var kind = (AddRemove)stream.ReadInt(); var value = ReadValueDelegate(SerializationContext, stream); ReceiveTrace?.Log($"{this} :: {kind} :: {value.PrintToString()}"); using (UsingDebugInfo()) { switch (kind) { case AddRemove.Add: mySet.Add(value); break; case AddRemove.Remove: mySet.Remove(value); break; default: throw new ArgumentOutOfRangeException(); } } }
public override void OnWireReceived(UnsafeReader stream) { var header = stream.ReadInt(); var msgVersioned = (header >> versionedFlagShift) != 0; var opType = header & ((1 << versionedFlagShift) - 1); var version = msgVersioned ? stream.ReadLong() : 0L; var key = ReadKeyDelegate(SerializationContext, stream); if (opType == Ack) { string error = null; if (!msgVersioned) { error = "Received ACK while msg hasn't versioned flag set"; } else if (!IsMaster) { error = "Received ACK when not a Master"; } else if (!myPendingForAck.TryGetValue(key, out var pendingVersion)) { error = "No pending for ACK"; } else if (pendingVersion < version) { error = $"Pending version `{pendingVersion}` < ACK version `{version}`"; } // Good scenario else if (pendingVersion == version) { myPendingForAck.Remove(key); } //else do nothing, silently drop var isError = !string.IsNullOrEmpty(error); if (ourLogReceived.IsTraceEnabled() || isError) { ourLogReceived.LogFormat(isError ? LoggingLevel.ERROR : LoggingLevel.TRACE, "{0} :: ACK :: key = {1} :: version = {2}{3}", this, key.PrintToString(), version, isError ? " >> " + error : ""); } } else { using (UsingDebugInfo()) { var kind = (AddUpdateRemove)opType; switch (kind) { case AddUpdateRemove.Add: case AddUpdateRemove.Update: var value = ReadValueDelegate(SerializationContext, stream); ReceiveTrace?.Log($"{this} :: {kind} :: key = {key.PrintToString()}" + (msgVersioned ? " :: version = " + version : "") + $" :: value = {value.PrintToString()}" ); if (msgVersioned || !IsMaster || !myPendingForAck.ContainsKey(key)) { myMap[key] = value; } else { ReceiveTrace?.Log(">> CHANGE IGNORED"); } break; case AddUpdateRemove.Remove: ReceiveTrace?.Log($"{this} :: {kind} :: key = {key.PrintToString()}" + (msgVersioned ? " :: version = " + version : "") ); if (msgVersioned || !IsMaster || !myPendingForAck.ContainsKey(key)) { myMap.Remove(key); } else { ReceiveTrace?.Log(">> CHANGE IGNORED"); } break; default: throw new ArgumentOutOfRangeException(kind.ToString()); } } if (msgVersioned) { Wire.Send(RdId, (innerWriter) => { innerWriter.Write((1 << versionedFlagShift) | Ack); innerWriter.Write(version); WriteKeyDelegate.Invoke(SerializationContext, innerWriter, key); SendTrace?.Log($"{this} :: ACK :: key = {key.PrintToString()} :: version = {version}"); }); if (IsMaster) { ourLogReceived.Error("Both ends are masters: {0}", Location); } } } }
public override void OnWireReceived(UnsafeReader stream) { var header = stream.ReadLong(); var opType = header & ((1 << versionedFlagShift) - 1); var version = header >> versionedFlagShift; var index = stream.ReadInt(); var kind = (AddUpdateRemove)opType; V value = default(V); var isPut = kind == AddUpdateRemove.Add || kind == AddUpdateRemove.Update; if (isPut) { value = ReadValueDelegate(SerializationContext, stream); } ReceiveTrace?.Log( $"list `{Location}` ({RdId}) :: {kind} :: index={index} :: version = {version}{(isPut ? " :: value = " + value.PrintToString() : "")}"); if (version != myNextVersion) { Assertion.Fail("Version conflict for {0} Expected version {1} received {2}. Are you modifying a list from two sides?", Location, myNextVersion, version); } myNextVersion++; using (UsingDebugInfo()) { switch (kind) { case AddUpdateRemove.Add: if (index < 0) { myList.Add(value); } else { myList.Insert(index, value); } break; case AddUpdateRemove.Update: // ReSharper disable once AssignNullToNotNullAttribute myList[index] = value; break; case AddUpdateRemove.Remove: myList.RemoveAt(index); break; default: throw new ArgumentOutOfRangeException(kind.ToString()); } } }