Akka.Remote.Transport.Transport.Associate C# (CSharp) Method

Associate() public abstract method

Asynchronously opens a logical duplex link between two Transport entities over a network. It could be backed with a real transport layer connection (TCP), socketless connections provided over datagram protocols (UDP), and more. This call returns a Task of an AssociationHandle. A faulted Task indicates that the association attempt was unsuccessful. If the exception is InvalidAssociationException then the association request was invalid and it's impossible to recover.
public abstract Associate ( Akka.Actor.Address remoteAddress ) : Task
remoteAddress Akka.Actor.Address The address of the remote transport entity.
return Task
        public abstract Task<AssociationHandle> Associate(Address remoteAddress);

Usage Example

        protected override void Ready(object message)
        {
            if (message is InboundAssociation)
            {
                var ia            = message as InboundAssociation;
                var wrappedHandle = WrapHandle(ia.Association, associationListener, true);
                wrappedHandle.ThrottlerActor.Tell(new Handle(wrappedHandle));
            }
            else if (message is AssociateUnderlying)
            {
                var ua = message as AssociateUnderlying;

                // Slight modification of PipeTo, only success is sent, failure is propagated to a separate Task
                var associateTask = WrappedTransport.Associate(ua.RemoteAddress);
                var self          = Self;
                associateTask.ContinueWith(tr =>
                {
                    if (tr.IsFaulted)
                    {
                        ua.StatusPromise.SetException(tr.Exception ?? new Exception("association failed"));
                    }
                    else
                    {
                        self.Tell(new AssociateResult(tr.Result, ua.StatusPromise));
                    }
                }, TaskContinuationOptions.AttachedToParent
                                           & TaskContinuationOptions.ExecuteSynchronously);
            }
            else if (message is AssociateResult) // Finished outbound association and got back the handle
            {
                var ar            = message as AssociateResult;
                var wrappedHandle = WrapHandle(ar.AssociationHandle, associationListener, false);
                var naked         = NakedAddress(ar.AssociationHandle.RemoteAddress);
                var inMode        = GetInboundMode(naked);
                wrappedHandle.OutboundThrottleMode.Value = GetOutboundMode(naked);
                wrappedHandle.ReadHandlerSource.Task.ContinueWith(tr => new ListenerAndMode(tr.Result, inMode), TaskContinuationOptions.AttachedToParent & TaskContinuationOptions.ExecuteSynchronously)
                .PipeTo(wrappedHandle.ThrottlerActor);
                _handleTable.Add(Tuple.Create(naked, wrappedHandle));
                ar.StatusPromise.SetResult(wrappedHandle);
            }
            else if (message is SetThrottle)
            {
                var st    = message as SetThrottle;
                var naked = NakedAddress(st.Address);
                _throttlingModes[naked] = new Tuple <ThrottleMode, ThrottleTransportAdapter.Direction>(st.Mode, st.Direction);
                var ok    = Task.FromResult(SetThrottleAck.Instance);
                var modes = new List <Task <SetThrottleAck> >()
                {
                    ok
                };
                foreach (var handle in _handleTable)
                {
                    if (handle.Item1 == naked)
                    {
                        modes.Add(SetMode(handle.Item2, st.Mode, st.Direction));
                    }
                }

                var sender = Sender;
                Task.WhenAll(modes).ContinueWith(tr =>
                {
                    return(SetThrottleAck.Instance);
                },
                                                 TaskContinuationOptions.AttachedToParent & TaskContinuationOptions.ExecuteSynchronously)
                .PipeTo(sender);
            }
            else if (message is ForceDisassociate)
            {
                var fd    = message as ForceDisassociate;
                var naked = NakedAddress(fd.Address);
                foreach (var handle in _handleTable)
                {
                    if (handle.Item1 == naked)
                    {
                        handle.Item2.Disassociate();
                    }
                }

                /*
                 * NOTE: Important difference between Akka.NET and Akka here.
                 * In canonical Akka, ThrottleHandlers are never removed from
                 * the _handleTable. The reason is because Ask-ing a terminated ActorRef
                 * doesn't cause any exceptions to be thrown upstream - it just times out
                 * and propagates a failed Future.
                 *
                 * In the CLR, a CancellationException gets thrown and causes all
                 * parent tasks chaining back to the EndPointManager to fail due
                 * to an Ask timeout.
                 *
                 * So in order to avoid this problem, we remove any disassociated handles
                 * from the _handleTable.
                 *
                 * Questions? Ask @Aaronontheweb
                 */
                _handleTable.RemoveAll(tuple => tuple.Item1 == naked);
                Sender.Tell(ForceDisassociateAck.Instance);
            }
            else if (message is ForceDisassociateExplicitly)
            {
                var fde   = message as ForceDisassociateExplicitly;
                var naked = NakedAddress(fde.Address);
                foreach (var handle in _handleTable)
                {
                    if (handle.Item1 == naked)
                    {
                        handle.Item2.DisassociateWithFailure(fde.Reason);
                    }
                }

                /*
                 * NOTE: Important difference between Akka.NET and Akka here.
                 * In canonical Akka, ThrottleHandlers are never removed from
                 * the _handleTable. The reason is because Ask-ing a terminated ActorRef
                 * doesn't cause any exceptions to be thrown upstream - it just times out
                 * and propagates a failed Future.
                 *
                 * In the CLR, a CancellationException gets thrown and causes all
                 * parent tasks chaining back to the EndPointManager to fail due
                 * to an Ask timeout.
                 *
                 * So in order to avoid this problem, we remove any disassociated handles
                 * from the _handleTable.
                 *
                 * Questions? Ask @Aaronontheweb
                 */
                _handleTable.RemoveAll(tuple => tuple.Item1 == naked);
                Sender.Tell(ForceDisassociateAck.Instance);
            }
            else if (message is Checkin)
            {
                var chkin = message as Checkin;
                var naked = NakedAddress(chkin.Origin);
                _handleTable.Add(new Tuple <Address, ThrottlerHandle>(naked, chkin.ThrottlerHandle));
                SetMode(naked, chkin.ThrottlerHandle);
            }
        }