예제 #1
0
 public override void ProcessLinkUtility(IPeerNeighbor neighbor, UtilityInfo utilityInfo)
 {
     if (!PeerNeighborStateHelper.IsConnected(neighbor.State))
     {
         neighbor.Abort(PeerCloseReason.InvalidNeighbor, PeerCloseInitiator.LocalNode);
     }
     else
     {
         try
         {
             UtilityExtension.ProcessLinkUtility(neighbor, utilityInfo);
         }
         catch (Exception exception)
         {
             if (Fx.IsFatal(exception))
             {
                 throw;
             }
             if (PeerFlooderBase <Message, UtilityInfo> .CloseNeighborIfKnownException(base.neighborManager, exception, neighbor) != null)
             {
                 throw;
             }
             DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information);
         }
     }
 }
예제 #2
0
        public override void ProcessLinkUtility(IPeerNeighbor neighbor, UtilityInfo utilityInfo)
        {
            if (!PeerNeighborStateHelper.IsConnected(neighbor.State))
            {
                neighbor.Abort(PeerCloseReason.InvalidNeighbor, PeerCloseInitiator.LocalNode);
                return;
            }

            try
            {
                UtilityExtension.ProcessLinkUtility(neighbor, utilityInfo);
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }
                if (null != CloseNeighborIfKnownException(neighborManager, e, neighbor))
                {
                    throw;
                }
                DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
            }
        }
예제 #3
0
        void IFlooderForThrottle.OnThrottleReached()
        {
            if (DiagnosticUtility.ShouldTraceInformation)
            {
                string message = SR.GetString(SR.PeerThrottleWaiting, this.config.MeshId);
                PeerThrottleTraceRecord record = new PeerThrottleTraceRecord(this.config.MeshId, message);
                TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.PeerFlooderReceiveMessageQuotaExceeded,
                                        SR.GetString(SR.TraceCodePeerFlooderReceiveMessageQuotaExceeded), record, this, null);
            }

            IPeerNeighbor peer = this.neighborManager.SlowestNeighbor();

            if (peer == null)
            {
                return;
            }
            UtilityExtension extension = peer.Utility;

            if (peer.IsConnected && extension != null)
            {
                if (extension.PendingMessages > PeerTransportConstants.MessageThreshold)
                {
                    extension.BeginCheckPoint(new UtilityExtension.PruneNeighborCallback(PruneNeighborCallback));
                }
                else
                {
                    Fx.Assert(false, "Neighbor is marked slow with messages " + extension.PendingMessages);
                }
                FireReachedEvent();
            }
        }
예제 #4
0
        public static void OnMessageSent(IPeerNeighbor neighbor)
        {
            UtilityExtension ext = neighbor.Extensions.Find <UtilityExtension>();

            if (ext != null)
            {
                ext.OnMessageSent();
            }
        }
        public static void ProcessLinkUtility(IPeerNeighbor neighbor, UtilityInfo umessage)
        {
            UtilityExtension extension = neighbor.Extensions.Find <UtilityExtension>();

            if (extension != null)
            {
                extension.ProcessLinkUtility(umessage.Useful, umessage.Total);
            }
        }
        public static void OnNeighborClosed(IPeerNeighbor neighbor)
        {
            UtilityExtension item = neighbor.Extensions.Find <UtilityExtension>();

            if (item != null)
            {
                neighbor.Extensions.Remove(item);
            }
        }
예제 #7
0
        static public void OnNeighborClosed(IPeerNeighbor neighbor)
        {
            Fx.Assert(neighbor != null, "Neighbor must have a value");
            UtilityExtension ext = neighbor.Extensions.Find <UtilityExtension>();

            if (ext != null)
            {
                neighbor.Extensions.Remove(ext);
            }
        }
예제 #8
0
        static public void ProcessLinkUtility(IPeerNeighbor neighbor, UtilityInfo umessage)
        {
            Fx.Assert(neighbor != null, "Neighbor must have a value");
            UtilityExtension ext = neighbor.Extensions.Find <UtilityExtension>();

            if (ext != null)
            {
                ext.ProcessLinkUtility(umessage.Useful, umessage.Total);
            }
        }
        public static uint UpdateLinkUtility(IPeerNeighbor neighbor, bool useful)
        {
            uint             num       = 0;
            UtilityExtension extension = neighbor.Extensions.Find <UtilityExtension>();

            if (extension != null)
            {
                num = extension.UpdateLinkUtility(useful);
            }
            return(num);
        }
 internal static void ReportCacheMiss(IPeerNeighbor neighbor, int missedBy)
 {
     if (neighbor.IsConnected)
     {
         UtilityExtension extension = neighbor.Extensions.Find <UtilityExtension>();
         if (extension != null)
         {
             extension.ReportCacheMiss(missedBy);
         }
     }
 }
 public static void OnEndSend(IPeerNeighbor neighbor, FloodAsyncResult fresult)
 {
     if (neighbor.State < PeerNeighborState.Disconnecting)
     {
         UtilityExtension utility = neighbor.Utility;
         if (utility != null)
         {
             utility.OnEndSend(fresult);
         }
     }
 }
예제 #12
0
        public static uint UpdateLinkUtility(IPeerNeighbor neighbor, bool useful)
        {
            Fx.Assert(neighbor != null, "Neighbor must have a value");
            uint             linkUtility = 0;
            UtilityExtension ext         = neighbor.Extensions.Find <UtilityExtension>();

            if (ext != null)
            {
                // Can happen if the neighbor has been closed for instance
                linkUtility = ext.UpdateLinkUtility(useful);
            }
            return(linkUtility);
        }
예제 #13
0
        public static void OnEndSend(IPeerNeighbor neighbor, FloodAsyncResult fresult)
        {
            if (neighbor.State >= PeerNeighborState.Disconnecting)
            {
                return;
            }
            UtilityExtension instance = neighbor.Utility;

            if (instance == null)
            {
                return;
            }
            instance.OnEndSend(fresult);
        }
예제 #14
0
        static internal void ReportCacheMiss(IPeerNeighbor neighbor, int missedBy)
        {
            Fx.Assert(missedBy > AcceptableMissDistance, "Call this method for cache misses ONLY!");
            Fx.Assert(neighbor != null, "Neighbor must have a value");

            if (!neighbor.IsConnected)
            {
                return;
            }
            UtilityExtension ext = neighbor.Extensions.Find <UtilityExtension>();

            if (ext != null)
            {
                ext.ReportCacheMiss(missedBy);
            }
        }
예제 #15
0
        IPeerNeighbor IPeerMaintainer.GetLeastUsefulNeighbor()
        {
            IPeerNeighbor neighbor = null;
            uint          maxValue = uint.MaxValue;

            foreach (IPeerNeighbor neighbor2 in this.neighborManager.GetConnectedNeighbors())
            {
                UtilityExtension extension = neighbor2.Extensions.Find <UtilityExtension>();
                if (((extension != null) && extension.IsAccurate) && ((extension.LinkUtility < maxValue) && !neighbor2.IsClosing))
                {
                    maxValue = extension.LinkUtility;
                    neighbor = neighbor2;
                }
            }
            return(neighbor);
        }
        IPeerNeighbor IPeerMaintainer.GetLeastUsefulNeighbor()
        {
            IPeerNeighbor leastUsefulNeighbor = null;
            uint          minUtility          = UInt32.MaxValue;

            foreach (IPeerNeighbor neighbor in this.neighborManager.GetConnectedNeighbors())
            {
                UtilityExtension utilityExtension = neighbor.Extensions.Find <UtilityExtension>();
                if (utilityExtension != null && utilityExtension.IsAccurate && utilityExtension.LinkUtility < minUtility && !neighbor.IsClosing)
                {
                    minUtility          = utilityExtension.LinkUtility;
                    leastUsefulNeighbor = neighbor;
                }
            }
            return(leastUsefulNeighbor);
        }
        protected IAsyncResult BeginSendHelper(IPeerNeighbor neighbor, TimeSpan timeout, Message message, FloodAsyncResult fresult)
        {
            IAsyncResult result = null;
            IAsyncResult result2;
            bool         flag = false;

            try
            {
                UtilityExtension.OnMessageSent(neighbor);
                result = neighbor.BeginSend(message, timeout, Fx.ThunkCallback(new AsyncCallback(fresult.OnSendComplete)), message);
                fresult.AddResult(result, neighbor);
                if (result.CompletedSynchronously)
                {
                    neighbor.EndSend(result);
                    UtilityExtension.OnEndSend(neighbor, fresult);
                }
                result2 = result;
            }
            catch (Exception exception)
            {
                if (Fx.IsFatal(exception))
                {
                    flag = true;
                    throw;
                }
                if (PeerFlooderBase <TFloodContract, TLinkContract> .CloseNeighborIfKnownException(this.neighborManager, exception, neighbor) != null)
                {
                    fresult.MarkEnd(false);
                    throw;
                }
                System.ServiceModel.DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information);
                result2 = null;
            }
            finally
            {
                if (((result == null) || result.CompletedSynchronously) && !flag)
                {
                    message.Close();
                }
            }
            return(result2);
        }
예제 #18
0
        protected IAsyncResult BeginSendHelper(IPeerNeighbor neighbor, TimeSpan timeout, Message message, FloodAsyncResult fresult)
        {
            IAsyncResult result = null;
            bool         fatal  = false;

            try
            {
                UtilityExtension.OnMessageSent(neighbor);
                result = neighbor.BeginSend(message, timeout, Fx.ThunkCallback(new AsyncCallback(fresult.OnSendComplete)), message);
                fresult.AddResult(result, neighbor);
                if (result.CompletedSynchronously)
                {
                    neighbor.EndSend(result);
                    UtilityExtension.OnEndSend(neighbor, fresult);
                }
                return(result);
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    fatal = true;
                    throw;
                }
                if (null != CloseNeighborIfKnownException(neighborManager, e, neighbor))
                {
                    fresult.MarkEnd(false);
                    throw;
                }

                DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                return(null);
            }
            finally
            {
                if ((result == null || result.CompletedSynchronously) && !fatal)
                {
                    message.Close();
                }
            }
        }
        void IFlooderForThrottle.OnThrottleReached()
        {
            if (System.ServiceModel.DiagnosticUtility.ShouldTraceInformation)
            {
                string message = System.ServiceModel.SR.GetString("PeerThrottleWaiting", new object[] { this.config.MeshId });
                PeerThrottleTraceRecord extendedData = new PeerThrottleTraceRecord(this.config.MeshId, message);
                TraceUtility.TraceEvent(TraceEventType.Information, 0x4004f, System.ServiceModel.SR.GetString("TraceCodePeerFlooderReceiveMessageQuotaExceeded"), extendedData, this, null);
            }
            IPeerNeighbor neighbor = this.neighborManager.SlowestNeighbor();

            if (neighbor != null)
            {
                UtilityExtension utility = neighbor.Utility;
                if (neighbor.IsConnected && (utility != null))
                {
                    if (utility.PendingMessages > 0x20)
                    {
                        utility.BeginCheckPoint(new System.ServiceModel.Channels.UtilityExtension.PruneNeighborCallback(this.PruneNeighborCallback));
                    }
                    this.FireReachedEvent();
                }
            }
        }
        public virtual IAsyncResult OnFloodedMessage(IPeerNeighbor neighbor, TFloodContract floodInfo, AsyncCallback callback, object state)
        {
            bool                useful        = false;
            MessageBuffer       messageBuffer = null;
            Message             message       = null;
            int                 index         = 0;
            ulong               maxValue      = ulong.MaxValue;
            MessageHeader       hopHeader     = null;
            bool                flag2         = false;
            PeerMessageProperty property      = null;
            IAsyncResult        result        = null;

            try
            {
                property = (PeerMessageProperty)floodInfo.Properties["PeerProperty"];
                if (!property.MessageVerified)
                {
                    if (property.CacheMiss > 2)
                    {
                        UtilityExtension.ReportCacheMiss(neighbor, property.CacheMiss);
                    }
                    result = new CompletedAsyncResult(callback, state);
                }
                else
                {
                    useful        = true;
                    messageBuffer = floodInfo.CreateBufferedCopy((int)this.config.MaxReceivedMessageSize);
                    message       = messageBuffer.CreateMessage();
                    Uri peerVia = property.PeerVia;
                    Uri peerTo  = property.PeerTo;
                    message.Headers.To = message.Properties.Via = peerVia;
                    index = this.UpdateHopCount(message, out hopHeader, out maxValue);
                    PeerMessagePropagation localAndRemote = PeerMessagePropagation.LocalAndRemote;
                    if (property.SkipLocalChannels)
                    {
                        localAndRemote = PeerMessagePropagation.Remote;
                    }
                    else if (this.messageHandler.HasMessagePropagation)
                    {
                        using (Message message2 = messageBuffer.CreateMessage())
                        {
                            localAndRemote = this.messageHandler.DetermineMessagePropagation(message2, PeerMessageOrigination.Remote);
                        }
                    }
                    if (((localAndRemote & PeerMessagePropagation.Remote) != PeerMessagePropagation.None) && (maxValue == 0L))
                    {
                        localAndRemote &= ~PeerMessagePropagation.Remote;
                    }
                    if ((localAndRemote & PeerMessagePropagation.Remote) != PeerMessagePropagation.None)
                    {
                        result = this.BeginFloodReceivedMessage(neighbor, messageBuffer, PeerTransportConstants.ForwardTimeout, callback, state, index, hopHeader);
                    }
                    else
                    {
                        result = new CompletedAsyncResult(callback, state);
                    }
                    if ((localAndRemote & PeerMessagePropagation.Local) != PeerMessagePropagation.None)
                    {
                        this.messageHandler.HandleIncomingMessage(messageBuffer, localAndRemote, index, hopHeader, peerVia, peerTo);
                    }
                }
                UtilityExtension.UpdateLinkUtility(neighbor, useful);
            }
            catch (Exception exception)
            {
                if (Fx.IsFatal(exception))
                {
                    flag2 = true;
                    throw;
                }
                if (PeerFlooderBase <TFloodContract, TLinkContract> .CloseNeighborIfKnownException(this.neighborManager, exception, neighbor) != null)
                {
                    throw;
                }
                System.ServiceModel.DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information);
            }
            finally
            {
                if (!flag2)
                {
                    if (message != null)
                    {
                        message.Close();
                    }
                    if (messageBuffer != null)
                    {
                        messageBuffer.Close();
                    }
                }
            }
            return(result);
        }
예제 #21
0
        internal void OnSendComplete(IAsyncResult result)
        {
            bool          flag     = false;
            IPeerNeighbor neighbor = null;
            bool          flag2    = false;

            if (!this.isCompleted)
            {
                Message asyncState = (Message)result.AsyncState;
                lock (this.ThisLock)
                {
                    if (this.isCompleted)
                    {
                        return;
                    }
                    if (!this.results.TryGetValue(result, out neighbor))
                    {
                        if (this.doneAdding)
                        {
                            throw Fx.AssertAndThrow("IAsyncResult is un-accounted for.");
                        }
                        this.pending.Add(result);
                        return;
                    }
                    this.results.Remove(result);
                    try
                    {
                        if (!result.CompletedSynchronously)
                        {
                            neighbor.EndSend(result);
                            this.offNode = true;
                            UtilityExtension.OnEndSend(neighbor, this);
                        }
                    }
                    catch (Exception exception)
                    {
                        if (Fx.IsFatal(exception))
                        {
                            flag2 = true;
                            throw;
                        }
                        Exception exception2 = PeerFlooderBase <Message, UtilityInfo> .CloseNeighborIfKnownException(this.pnm, exception, neighbor);

                        if (((exception2 != null) && this.doneAdding) && !this.shouldCallComplete)
                        {
                            throw;
                        }
                        if (this.exception == null)
                        {
                            this.exception = exception2;
                        }
                        DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information);
                    }
                    finally
                    {
                        if (((asyncState != null) && !result.CompletedSynchronously) && !flag2)
                        {
                            asyncState.Close();
                        }
                    }
                    if (((this.results.Count == 0) && this.doneAdding) && this.shouldCallComplete)
                    {
                        this.isCompleted = true;
                        flag             = true;
                    }
                }
                if (flag && this.shouldCallComplete)
                {
                    this.CompleteOp(false);
                }
            }
        }
예제 #22
0
        public virtual IAsyncResult OnFloodedMessage(IPeerNeighbor neighbor, TFloodContract floodInfo, AsyncCallback callback, object state)
        {
            bool                process       = false;
            MessageBuffer       messageBuffer = null;
            Message             message       = null;
            Uri                 via;
            Uri                 to;
            int                 index         = 0;
            ulong               remainingHops = PeerTransportConstants.MaxHopCount;
            MessageHeader       hopHeader     = null;
            bool                fatal         = false;
            PeerMessageProperty peerProperty  = null;
            IAsyncResult        result        = null;

            try
            {
                peerProperty = (PeerMessageProperty)floodInfo.Properties[PeerStrings.PeerProperty];
                if (!peerProperty.MessageVerified)
                {
                    if (peerProperty.CacheMiss > UtilityExtension.AcceptableMissDistance)
                    {
                        UtilityExtension.ReportCacheMiss(neighbor, peerProperty.CacheMiss);
                    }
                    result = new CompletedAsyncResult(callback, state);
                }
                else
                {
                    process            = true;
                    messageBuffer      = floodInfo.CreateBufferedCopy((int)this.config.MaxReceivedMessageSize);
                    message            = messageBuffer.CreateMessage();
                    via                = peerProperty.PeerVia;
                    to                 = peerProperty.PeerTo;
                    message.Headers.To = message.Properties.Via = via;

                    index = UpdateHopCount(message, out hopHeader, out remainingHops);

                    PeerMessagePropagation propagateFlags = PeerMessagePropagation.LocalAndRemote;
                    if (peerProperty.SkipLocalChannels)
                    {
                        propagateFlags = PeerMessagePropagation.Remote;
                    }
                    else if (messageHandler.HasMessagePropagation)
                    {
                        using (Message filterMessage = messageBuffer.CreateMessage())
                        {
                            propagateFlags = messageHandler.DetermineMessagePropagation(filterMessage, PeerMessageOrigination.Remote);
                        }
                    }

                    if ((propagateFlags & PeerMessagePropagation.Remote) != 0)
                    {
                        if (remainingHops == 0)
                        {
                            propagateFlags &= ~PeerMessagePropagation.Remote;
                        }
                    }
                    if ((propagateFlags & PeerMessagePropagation.Remote) != 0)
                    {
                        result = BeginFloodReceivedMessage(neighbor, messageBuffer, PeerTransportConstants.ForwardTimeout, callback, state, index, hopHeader);
                    }
                    else
                    {
                        result = new CompletedAsyncResult(callback, state);
                    }
                    if ((propagateFlags & PeerMessagePropagation.Local) != 0)
                    {
                        messageHandler.HandleIncomingMessage(messageBuffer, propagateFlags, index, hopHeader, via, to);
                    }
                }
                UtilityExtension.UpdateLinkUtility(neighbor, process);
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    fatal = true;
                    throw;
                }
                if (null != CloseNeighborIfKnownException(neighborManager, e, neighbor))
                {
                    throw;
                }
                DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
            }
            finally
            {
                if (!fatal)
                {
                    if (message != null)
                    {
                        message.Close();
                    }
                    if (messageBuffer != null)
                    {
                        messageBuffer.Close();
                    }
                }
            }
            return(result);
        }
예제 #23
0
        //this is the callback routine for async completion on channel BeginSend() operations.
        //if we are done, simply return. This can happen if user called sync EndX.
        //if the flooder is still processing BeginSend(), then we probably cant complete. In this case, add the result to pending and return
        //main thread will flush the pending completions in MarkEnd().
        //otherwise, call EndX on the result and remove it from results.
        //if this is the last invoke, signal user using base.Complete AND isCompleted=true
        internal void OnSendComplete(IAsyncResult result)
        {
            bool          callComplete = false;
            IPeerNeighbor neighbor     = null;
            bool          fatal        = false;

            if (isCompleted)
            {
                return;
            }
            Message message = (Message)result.AsyncState;

            //wait until flooder had a chance to call all outgoing channels and give us Async results.
            lock (ThisLock)
            {
                if (isCompleted)
                {
                    return;
                }

                if (!this.results.TryGetValue(result, out neighbor))
                {
                    if (!doneAdding)
                    {
                        this.pending.Add(result);
                    }
                    else
                    {
                        throw Fx.AssertAndThrow("IAsyncResult is un-accounted for.");
                    }
                    return;
                }
                this.results.Remove(result);

                try
                {
                    //try doing this only if the async result is marked !CompletedSynchronously.
                    if (!result.CompletedSynchronously)
                    {
                        neighbor.EndSend(result);
                        offNode = true;
                        UtilityExtension.OnEndSend(neighbor, this);
                    }
                }
                catch (Exception e)
                {
                    if (Fx.IsFatal(e))
                    {
                        fatal = true;
                        throw;
                    }

                    Exception temp = PeerFlooder.CloseNeighborIfKnownException(pnm, e, neighbor);
                    //we want to return the very first exception to the user.
                    if (temp != null && this.doneAdding && !this.shouldCallComplete)
                    {
                        throw;
                    }
                    if (this.exception == null)
                    {
                        this.exception = temp;
                    }
                    DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                }
                finally
                {
                    if (message != null && !result.CompletedSynchronously && !fatal)
                    {
                        message.Close();
                    }
                }
                //dont want to call Complete from the lock.
                //we just decide if this thread should call complete and call outside the lock.
                if (this.results.Count == 0 && this.doneAdding && this.shouldCallComplete)
                {
                    this.isCompleted = true;
                    callComplete     = true;
                }
            }
            //if we are done with callbacks and beginx calls,
            if (callComplete && this.shouldCallComplete)
            {
                CompleteOp(false);
            }
        }