예제 #1
0
        private async Task RunAsyncHelper()
        {
            try {
                await Task.WhenAny(
                    shutdownCancellationTokenSource.Token.AsTask(),
                    Task.WhenAll(
                        Go(async() => {
                    var remoteToLocalHandshake = (HandshakeDto)await payloadUtils.ReadPayloadAsync(ns, shutdownCancellationTokenSource.Token).ConfigureAwait(false);
                    remoteIdentity             = remoteToLocalHandshake.Identity;
                }),
                        Go(async() => {
                    var localToRemoteHandshake = new HandshakeDto {
                        Identity = localIdentity
                    };
                    await payloadUtils.WritePayloadAsync(ns, localToRemoteHandshake, writerLock, shutdownCancellationTokenSource.Token).ConfigureAwait(false);
                }))).ConfigureAwait(false);

                if (shutdownCancellationTokenSource.IsCancellationRequested)
                {
                    return;
                }

                isHandshakeComplete = true;

                var readerTask = RunReaderAsync(shutdownCancellationTokenSource.Token).Forgettable();
                var writerTask = RunWriterAsync(shutdownCancellationTokenSource.Token).Forgettable();

                tcpRoutingContextContainer.AssociateRemoteIdentityOrThrow(remoteIdentity.Id, this);
                routingTable.Register(remoteIdentity.Id, this);

                peerTable.GetOrAdd(remoteIdentity.Id).HandleInboundPeerIdentityUpdate(remoteIdentity);

                configuration.HandleRemoteHandshakeCompletion(remoteIdentity);

                try {
                    await Task.WhenAny(
                        readerTask,
                        writerTask,
                        shutdownCancellationTokenSource.Token.AsTask()
                        ).ConfigureAwait(false);

                    shutdownCancellationTokenSource.Cancel();
                } catch (OperationCanceledException) when(isShutdown)
                {
                }
            } catch (Exception e) {
                Debug($"RunAsync threw {e}");
            } finally {
                if (remoteIdentity != null)
                {
                    routingTable.Unregister(remoteIdentity.Id, this);
                    tcpRoutingContextContainer.RemoveOrThrow(this);
                    tcpRoutingContextContainer.UnassociateRemoteIdentityOrThrow(remoteIdentity.Id, this);
                }
            }
        }