Пример #1
0
        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));
                    }
                });
            }
        }
Пример #2
0
        public override void OnWireReceived(UnsafeReader reader)
        {
            var value = myReadValue(SerializationContext, reader);

            ReceiveTrace?.Log($"{this} :: value = {value.PrintToString()}");
            using (UsingDebugInfo())
                mySignal.Fire(value);
        }
Пример #3
0
        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));
                    }
                });
            }
        }
Пример #4
0
        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;
            }
        }
Пример #5
0
        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}");
                }
            }
        }
Пример #6
0
Файл: RdSet.cs Проект: yvvan/rd
        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();
                }
            }
        }
Пример #7
0
Файл: RdMap.cs Проект: yvvan/rd
        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);
                    }
                }
            }
        }
Пример #8
0
        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());
                }
            }
        }