public PeerNeighborCloseEventArgs(PeerCloseReason reason,
                                   PeerCloseInitiator closeInitiator, Exception exception)
 {
     this.reason         = reason;
     this.closeInitiator = closeInitiator;
     this.exception      = exception;
 }
            // Close a neighbor gracefully
            public IAsyncResult BeginClose(PeerCloseReason reason,
                PeerCloseInitiator closeInit, Exception exception,
                AsyncCallback callback, object asyncState)
            {
                bool callClosing = false;

                lock (ThisLock)
                {
                    // Set close reason etc. if they are not already set.
                    if (!this.isClosing)
                    {
                        callClosing = true;
                        this.isClosing = true;
                        this.closeReason = reason;
                        this.closeInitiator = closeInit;
                        this.closeException = exception;
                    }
                }

                // Initiate close, if another thread has not already done so....
                // NOTE: NeighborClosing handlers should not throw any catchable exceptions.
                if (callClosing)
                {
                    EventHandler<PeerNeighborCloseEventArgs> handler = this.Closing;
                    if (handler != null)
                    {
                        try
                        {
                            PeerNeighborCloseEventArgs args = new PeerNeighborCloseEventArgs(
                                reason, closeInitiator, exception);
                            handler(this, args);
                        }
                        catch (Exception e)
                        {
                            if (Fx.IsFatal(e)) throw;
                            Abort();
                            throw;
                        }
                    }
                }

                if (this.channelFactory != null)
                    return this.channelFactory.BeginClose(callback, asyncState);
                else
                    return this.proxyChannel.BeginClose(callback, asyncState);
            }
 // NOTE: Closing handlers not invoked when a neighbor is aborted; but Closed handlers are.
 public void Abort(PeerCloseReason reason, PeerCloseInitiator closeInit)
 {
     lock (ThisLock)
     {
         // Set close reason etc. if they are not already set.
         if (!this.isClosing)
         {
             this.isClosing = true;
             this.closeReason = reason;
             this.closeInitiator = closeInit;
         }
     }
     Abort();
 }
 public PeerNeighbor(PeerNodeConfig config,
                     IPeerNodeMessageHandling messageHandler)
 {
     this.closeReason = PeerCloseReason.None;
     this.closeInitiator = PeerCloseInitiator.LocalNode;
     this.config = config;
     this.state = PeerNeighborState.Created;
     this.extensions = new ExtensionCollection<IPeerNeighbor>(this, thisLock);
     this.messageHandler = messageHandler;
 }
        // Calls neighbor.BeginClose or EndClose and catches appropriate exceptions for any cleanup.
        // We use a single method for both BeginClose and EndClose processing since exception handling
        // is very similar in both cases.
        void InvokeAsyncNeighborClose(PeerNeighbor neighbor, PeerCloseReason closeReason,
            PeerCloseInitiator closeInitiator, Exception closeException, IAsyncResult endResult)
        {
            // initiate invoking BeginClose or EndClose
            try
            {
                if (endResult == null)
                {
                    IAsyncResult beginResult = neighbor.BeginClose(closeReason, closeInitiator,
                                        closeException, Fx.ThunkCallback(new AsyncCallback(OnNeighborClosedCallback)), neighbor);
                    if (beginResult.CompletedSynchronously)
                        neighbor.EndClose(beginResult);
                }
                else
                {
                    neighbor.EndClose(endResult);
                }
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e)) throw;
                DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);

                neighbor.TraceEventHelper(TraceEventType.Warning, TraceCode.PeerNeighborCloseFailed, SR.GetString(SR.TraceCodePeerNeighborCloseFailed), e);
                // May get InvalidOperationException or ObjectDisposedException due to simultaneous close from both sides (and autoclose is enabled)
                if (e is InvalidOperationException || e is CommunicationException || e is TimeoutException)
                {
                    neighbor.Abort();
                }
                else
                {
                    throw;
                }
            }
        }
 static void FireEvent(EventHandler<PeerNeighborCloseEventArgs> handler,
     PeerNeighbor neighbor, PeerCloseReason closeReason,
     PeerCloseInitiator closeInitiator, Exception closeException)
 {
     if (handler != null)
     {
         PeerNeighborCloseEventArgs args = new PeerNeighborCloseEventArgs(
             closeReason, closeInitiator, closeException);
         handler(neighbor, args);
     }
 }
        public void CloseNeighbor(IPeerNeighbor neighbor, PeerCloseReason closeReason,
            PeerCloseInitiator closeInitiator, Exception closeException)
        {
            PeerNeighbor nbr = (PeerNeighbor)neighbor;

            lock (ThisLock)
            {
                if (!(this.state != State.Created))
                {
                    throw Fx.AssertAndThrow("Neighbor Manager is not expected to be in Created state");
                }

                // Check that the neighbor is known to neighbor manager
                if (!this.neighborList.Contains(nbr))
                    return;
            }

            // initiate closing of the neighbor
            if (closeReason != PeerCloseReason.InvalidNeighbor)
            {
                if (!nbr.IsClosing)
                    InvokeAsyncNeighborClose(nbr, closeReason, closeInitiator, closeException, null);
            }
            else    // Call abort even if neighbor is already closing
            {
                nbr.Abort(closeReason, closeInitiator);
            }
        }
 //
 // Close the specified neighbor. Ok to call multiple times, but NeighborClosing 
 // and NeighborClosed events are fired just once.
 // If the closeReason specified is InvalidNeighbor, it will be closed ungracefully
 //
 public void CloseNeighbor(IPeerNeighbor neighbor, PeerCloseReason closeReason,
     PeerCloseInitiator closeInitiator)
 {
     CloseNeighbor(neighbor, closeReason, closeInitiator, null);
 }
            // Does heavy-lifting of processing closed/faulted events
            void OnChannelClosedOrFaulted(PeerCloseReason reason)
            {
                PeerNeighborState oldState;

                lock (ThisLock)
                {
                    // We don't call SetState here because it should not be called inside lock,
                    // and to avoid race conditions, we need to set the state before the lock 
                    // can be released.
                    oldState = this.state;
                    this.state = PeerNeighborState.Closed;

                    // Set close reason etc. if they are not already set (as a result of local 
                    // node initiating Close)
                    if (!this.isClosing)
                    {
                        this.isClosing = true;
                        this.closeReason = reason;
                        this.closeInitiator = PeerCloseInitiator.RemoteNode;
                    }
                    TraceClosedEvent(oldState);
                }

                // Update traces and counters and notify interested parties
                OnStateChanged(PeerNeighborState.Closed);
            }
 public PeerNeighborCloseEventArgs(PeerCloseReason reason, PeerCloseInitiator closeInitiator, System.Exception exception)
 {
     this.reason = reason;
     this.closeInitiator = closeInitiator;
     this.exception = exception;
 }