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 = string.Format("Pending version `{0}` < ACK version `{1}`", pendingVersion, version); } // Good scenario else if (pendingVersion == version) { myPendingForAck.Remove(key); } //else do nothing, silently drop var isError = !string.IsNullOrEmpty(error); if (LogReceived.IsTraceEnabled() || isError) { LogReceived.LogFormat(isError ? LoggingLevel.ERROR : LoggingLevel.TRACE, "map `{0}` ({1}) :: ACK :: key = {2} :: version = {3}{4}", Location, RdId, 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); if (LogReceived.IsTraceEnabled()) { LogReceived.Trace("map `{0}` ({1}) :: {2} :: key = {3}{4} :: value = {5}", Location, RdId, kind, key.PrintToString(), msgVersioned ? " :: version = " + version : "", value.PrintToString()); } if (msgVersioned || !IsMaster || !myPendingForAck.ContainsKey(key)) { myMap[key] = value; } else { LogReceived.Trace(">> CHANGE IGNORED"); } break; case AddUpdateRemove.Remove: if (LogReceived.IsTraceEnabled()) { LogReceived.Trace("map `{0}` ({1}) :: {2} :: key = {3}{4}", Location, RdId, kind, key.PrintToString(), msgVersioned ? " :: version = " + version : ""); } if (msgVersioned || !IsMaster || !myPendingForAck.ContainsKey(key)) { myMap.Remove(key); } else { LogReceived.Trace(">> 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); if (LogSend.IsTraceEnabled()) { LogSend.Trace("map `{0}` ({1}) :: ACK :: key = {2} :: version = {3}", Location, RdId, key.PrintToString(), version); } }); if (IsMaster) { LogReceived.Error("Both ends are masters: {0}", Location); } } } }