Esempio n. 1
0
        private async Task ListenLoop(IAssociationEventListener listener)
        {
            while (!ShutdownToken.IsCancellationRequested)
            {
                Socket socket = null;
                try
                {
                    // Accept will throw when _listener is closed
                    socket = await Task <Socket> .Factory.FromAsync(_listener.BeginAccept, _listener.EndAccept, null);

                    Settings.ConfigureSocket(socket);

                    IPEndPoint remoteEndPoint = (IPEndPoint)socket.RemoteEndPoint;
                    string     host           = GetAddressString(remoteEndPoint.Address);

                    Settings.Log.Info("ListenLoop: Accepted new connection from '{0}:{1}'", host, remoteEndPoint.Port);

                    var remoteAddress = new Address(ProtocolName, System.Name, host, remoteEndPoint.Port);

                    var networkStream = new NetworkStream(socket, false);

                    CreateInboundAssociation(networkStream, remoteAddress, socket)
                    .ContinueWith(task =>
                    {
                        if (task.Status == TaskStatus.RanToCompletion)
                        {
                            listener.Notify(new InboundAssociation(task.Result));
                        }
                    }).IgnoreResult();
                }
                catch (SocketException ex)
                    when(ex.SocketErrorCode == SocketError.ConnectionReset ||
                         ex.SocketErrorCode == SocketError.TimedOut)
                    {
                        Settings.CloseSocket(socket);

                        if (ShutdownToken.IsCancellationRequested)
                        {
                            return;
                        }

                        // Tcp handshake failed on new connection, not fatal
                        Settings.Log.Warning("SocketException occured while accepting connection");
                    }
                catch (Exception ex)
                {
                    Settings.CloseSocket(socket);

                    if (ShutdownToken.IsCancellationRequested)
                    {
                        return;
                    }

                    // Should not happen if listen on Loopback or IPAny
                    //TODO Otherwise might need to rebind if network adapter was disabled/enabled

                    Settings.Log.Warning("Unexpected ListenLoop exception\n{0}", ex);
                }
            }
        }
Esempio n. 2
0
        private Task <IHandleEventListener> NotifyInboundHandler(AssociationHandle wrappedHandle,
                                                                 HandshakeInfo handshakeInfo, IAssociationEventListener associationEventListener)
        {
            var readHandlerPromise = new TaskCompletionSource <IHandleEventListener>();

            ListenForListenerRegistration(readHandlerPromise);

            associationEventListener.Notify(
                new InboundAssociation(
                    new AkkaProtocolHandle(_localAddress, handshakeInfo.Origin, readHandlerPromise, wrappedHandle, handshakeInfo, Self, _codec)));
            return(readHandlerPromise.Task);
        }
 private Receive Accepting(IAssociationEventListener listener)
 {
     return(message =>
     {
         var connected = message as Tcp.Connected;
         if (connected != null)
         {
             var actor = Context.ActorOf(Props.Create(() => new ConnectionAssociationActor(Sender)));
             var association = new ConnectionAssociationHandle(actor, connected.LocalAddress.ToAddress(Context.System),
                                                               connected.RemoteAddress.ToAddress(Context.System));
             listener.Notify(new InboundAssociation(association));
         }
         return false;
     });
 }
Esempio n. 4
0
 private Receive Accepting(IAssociationEventListener listener)
 {
     return message =>
     {
         var connected = message as Tcp.Connected;
         if (connected != null)
         {
             var actor = Context.ActorOf(Props.Create(() => new ConnectionAssociationActor(Sender)));
             var association = new ConnectionAssociationHandle(actor,
                 connected.LocalAddress.ToAddress(Context.System),
                 connected.RemoteAddress.ToAddress(Context.System));
             listener.Notify(new InboundAssociation(association));
         }
         return false;
     };
 }
Esempio n. 5
0
 /// <summary>
 /// TBD
 /// </summary>
 /// <param name="ev">TBD</param>
 public void Notify(IAssociationEvent ev)
 {
     if (ev is InboundAssociation && ShouldDropInbound(ev.AsInstanceOf <InboundAssociation>().Association.RemoteAddress, ev, "notify"))
     {
         //ignore
     }
     else
     {
         if (_upstreamListener == null)
         {
         }
         else
         {
             _upstreamListener.Notify(InterceptInboundAssociation(ev));
         }
     }
 }
Esempio n. 6
0
        private async Task ListenLoop(IAssociationEventListener listener)
        {
            while (!ShutdownToken.IsCancellationRequested)
            {
                NamedPipeServerStream stream = new NamedPipeServerStream(Settings.PipeName, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);

                //TODO Catch exceptions appropriately
                await Task.Factory.FromAsync(stream.BeginWaitForConnection, stream.EndWaitForConnection, null);

                string uniqueId      = Guid.NewGuid().ToString("N");
                var    remoteAddress = new Address(ProtocolName, System.Name, Settings.PipeName + "_" + uniqueId, 1);

                var association = CreateInboundAssociation(stream, remoteAddress);

                listener.Notify(new InboundAssociation(association));
            }
        }
Esempio n. 7
0
        private void InitializeFSM()
        {
            When(ThrottlerState.WaitExposedHandle, @event =>
            {
                if (@event.FsmEvent is ThrottlerManager.Handle && @event.StateData is Uninitialized)
                {
                    // register to downstream layer and wait for origin
                    OriginalHandle.ReadHandlerSource.SetResult(new ActorHandleEventListener(Self));
                    return
                    (GoTo(ThrottlerState.WaitOrigin)
                     .Using(
                         new ExposedHandle(
                             @event.FsmEvent.AsInstanceOf <ThrottlerManager.Handle>().ThrottlerHandle)));
                }
                return(null);
            });

            When(ThrottlerState.WaitOrigin, @event =>
            {
                if (@event.FsmEvent is InboundPayload && @event.StateData is ExposedHandle)
                {
                    var b = @event.FsmEvent.AsInstanceOf <InboundPayload>().Payload;
                    ThrottledMessages.Enqueue(b);
                    var origin = PeekOrigin(b);
                    if (origin != null)
                    {
                        Manager.Tell(new ThrottlerManager.Checkin(origin, @event.StateData.AsInstanceOf <ExposedHandle>().Handle));
                        return(GoTo(ThrottlerState.WaitMode));
                    }
                    return(Stay());
                }
                return(null);
            });

            When(ThrottlerState.WaitMode, @event =>
            {
                if (@event.FsmEvent is InboundPayload)
                {
                    var b = @event.FsmEvent.AsInstanceOf <InboundPayload>().Payload;
                    ThrottledMessages.Enqueue(b);
                    return(Stay());
                }

                if (@event.FsmEvent is ThrottleMode && @event.StateData is ExposedHandle)
                {
                    var mode            = @event.FsmEvent.AsInstanceOf <ThrottleMode>();
                    var exposedHandle   = @event.StateData.AsInstanceOf <ExposedHandle>().Handle;
                    InboundThrottleMode = mode;
                    try
                    {
                        if (mode is Blackhole)
                        {
                            ThrottledMessages = new Queue <ByteString>();
                            exposedHandle.Disassociate();
                            return(Stop());
                        }
                        else
                        {
                            AssociationHandler.Notify(new InboundAssociation(exposedHandle));
                            var self = Self;
                            exposedHandle.ReadHandlerSource.Task.ContinueWith(
                                r => new ThrottlerManager.Listener(r.Result),
                                TaskContinuationOptions.ExecuteSynchronously)
                            .PipeTo(self);
                            return(GoTo(ThrottlerState.WaitUpstreamListener));
                        }
                    }
                    finally
                    {
                        Sender.Tell(SetThrottleAck.Instance);
                    }
                }

                return(null);
            });

            When(ThrottlerState.WaitUpstreamListener, @event =>
            {
                if (@event.FsmEvent is InboundPayload)
                {
                    var b = @event.FsmEvent.AsInstanceOf <InboundPayload>();
                    ThrottledMessages.Enqueue(b.Payload);
                    return(Stay());
                }

                if (@event.FsmEvent is ThrottlerManager.Listener)
                {
                    UpstreamListener = @event.FsmEvent.AsInstanceOf <ThrottlerManager.Listener>().HandleEventListener;
                    Self.Tell(new Dequeue());
                    return(GoTo(ThrottlerState.Throttling));
                }

                return(null);
            });

            When(ThrottlerState.WaitModeAndUpstreamListener, @event =>
            {
                if (@event.FsmEvent is ThrottlerManager.ListenerAndMode)
                {
                    var listenerAndMode = @event.FsmEvent.AsInstanceOf <ThrottlerManager.ListenerAndMode>();
                    UpstreamListener    = listenerAndMode.HandleEventListener;
                    InboundThrottleMode = listenerAndMode.Mode;
                    Self.Tell(new Dequeue());
                    return(GoTo(ThrottlerState.Throttling));
                }

                if (@event.FsmEvent is InboundPayload)
                {
                    var b = @event.FsmEvent.AsInstanceOf <InboundPayload>();
                    ThrottledMessages.Enqueue(b.Payload);
                    return(Stay());
                }

                return(null);
            });

            When(ThrottlerState.Throttling, @event =>
            {
                if (@event.FsmEvent is ThrottleMode)
                {
                    var mode            = @event.FsmEvent.AsInstanceOf <ThrottleMode>();
                    InboundThrottleMode = mode;
                    if (mode is Blackhole)
                    {
                        ThrottledMessages = new Queue <ByteString>();
                    }
                    CancelTimer(DequeueTimerName);
                    if (ThrottledMessages.Any())
                    {
                        ScheduleDequeue(InboundThrottleMode.TimeToAvailable(MonotonicClock.GetNanos(), ThrottledMessages.Peek().Length));
                    }
                    Sender.Tell(SetThrottleAck.Instance);
                    return(Stay());
                }

                if (@event.FsmEvent is InboundPayload)
                {
                    ForwardOrDelay(@event.FsmEvent.AsInstanceOf <InboundPayload>().Payload);
                    return(Stay());
                }

                if (@event.FsmEvent is Dequeue)
                {
                    if (ThrottledMessages.Any())
                    {
                        var payload = ThrottledMessages.Dequeue();
                        UpstreamListener.Notify(new InboundPayload(payload));
                        InboundThrottleMode = InboundThrottleMode.TryConsumeTokens(MonotonicClock.GetNanos(),
                                                                                   payload.Length).Item1;
                        if (ThrottledMessages.Any())
                        {
                            ScheduleDequeue(InboundThrottleMode.TimeToAvailable(MonotonicClock.GetNanos(), ThrottledMessages.Peek().Length));
                        }
                    }
                    return(Stay());
                }

                return(null);
            });

            WhenUnhandled(@event =>
            {
                // we should always set the throttling mode
                if (@event.FsmEvent is ThrottleMode)
                {
                    InboundThrottleMode = @event.FsmEvent.AsInstanceOf <ThrottleMode>();
                    Sender.Tell(SetThrottleAck.Instance);
                    return(Stay());
                }

                if (@event.FsmEvent is Disassociated)
                {
                    return(Stop()); // not notifying the upstream handler is intentional: we are relying on heartbeating
                }

                if (@event.FsmEvent is FailWith)
                {
                    var reason = @event.FsmEvent.AsInstanceOf <FailWith>().FailReason;
                    if (UpstreamListener != null)
                    {
                        UpstreamListener.Notify(new Disassociated(reason));
                    }
                    return(Stop());
                }

                return(null);
            });

            if (Inbound)
            {
                StartWith(ThrottlerState.WaitExposedHandle, Uninitialized.Instance);
            }
            else
            {
                OriginalHandle.ReadHandlerSource.SetResult(new ActorHandleEventListener(Self));
                StartWith(ThrottlerState.WaitModeAndUpstreamListener, Uninitialized.Instance);
            }
        }