예제 #1
0
        protected override async Task RunInternal()
        {
            var preamble = await connectionPreambleHelper.Read(this.Context);

            await connectionPreambleHelper.Write(
                this.Context,
                new ConnectionPreamble
            {
                NodeIdentity           = Constants.SiloDirectConnectionId,
                NetworkProtocolVersion = this.connectionOptions.ProtocolVersion,
                SiloAddress            = this.myAddress,
                ClusterId = this.myClusterId
            });

            if (!ClientGrainId.TryParse(preamble.NodeIdentity, out var clientId))
            {
                throw new InvalidOperationException($"Unexpected connection id {preamble.NodeIdentity} on proxy endpoint from {preamble.SiloAddress?.ToString() ?? "unknown silo"}");
            }

            if (preamble.ClusterId != this.myClusterId)
            {
                throw new InvalidOperationException($@"Unexpected cluster id ""{preamble.ClusterId}"", expected ""{this.myClusterId}""");
            }

            try
            {
                this.gateway.RecordOpenedConnection(this, clientId);
                await base.RunInternal();
            }
            finally
            {
                this.gateway.RecordClosedConnection(this);
            }
        }
예제 #2
0
        protected override async Task RunInternal()
        {
            Exception error = default;

            try
            {
                await Task.WhenAll(ReadPreamble(), WritePreamble());

                this.MessageReceivedCounter = MessagingStatisticsGroup.GetMessageReceivedCounter(this.RemoteSiloAddress);
                this.MessageSentCounter     = MessagingStatisticsGroup.GetMessageSendCounter(this.RemoteSiloAddress);
                await base.RunInternal();
            }
            catch (Exception exception) when((error = exception) is null)
            {
                Debug.Fail("Execution should not be able to reach this point.");
            }
            finally
            {
                if (!(this.RemoteSiloAddress is null))
                {
                    this.connectionManager.OnConnectionTerminated(this.RemoteSiloAddress, this, error);
                }
            }

            async Task WritePreamble()
            {
                await connectionPreambleHelper.Write(
                    this.Context,
                    new ConnectionPreamble
                {
                    NodeIdentity           = Constants.SiloDirectConnectionId,
                    NetworkProtocolVersion = this.connectionOptions.ProtocolVersion,
                    SiloAddress            = this.LocalSiloAddress,
                    ClusterId = this.LocalClusterId
                });
            }

            async Task ReadPreamble()
            {
                var preamble = await connectionPreambleHelper.Read(this.Context);

                if (!preamble.NodeIdentity.Equals(Constants.SiloDirectConnectionId))
                {
                    throw new InvalidOperationException("Unexpected client connection on silo endpoint.");
                }

                if (preamble.ClusterId != LocalClusterId)
                {
                    throw new InvalidOperationException($@"Unexpected cluster id ""{preamble.ClusterId}"", expected ""{LocalClusterId}""");
                }

                if (preamble.SiloAddress is not null)
                {
                    this.RemoteSiloAddress = preamble.SiloAddress;
                    this.connectionManager.OnConnected(preamble.SiloAddress, this);
                }
            }
        }
예제 #3
0
        protected override async Task RunInternal()
        {
            Exception error = default;

            try
            {
                this.messageCenter.OnGatewayConnectionOpen();

                var myClusterId = clusterOptions.ClusterId;
                await connectionPreambleHelper.Write(
                    this.Context,
                    new ConnectionPreamble
                {
                    NetworkProtocolVersion = this.connectionOptions.ProtocolVersion,
                    NodeIdentity           = this.messageCenter.ClientId.GrainId,
                    SiloAddress            = null,
                    ClusterId = myClusterId
                });

                var preamble = await connectionPreambleHelper.Read(this.Context);

                this.Log.LogInformation(
                    "Established connection to {Silo} with protocol version {ProtocolVersion}",
                    preamble.SiloAddress,
                    preamble.NetworkProtocolVersion.ToString());

                if (preamble.ClusterId != myClusterId)
                {
                    throw new InvalidOperationException($@"Unexpected cluster id ""{preamble.ClusterId}"", expected ""{myClusterId}""");
                }

                await base.RunInternal();
            }
            catch (Exception exception) when((error = exception) is null)
            {
                Debug.Fail("Execution should not be able to reach this point.");
            }
            finally
            {
                this.connectionManager.OnConnectionTerminated(this.RemoteSiloAddress, this, error);
                this.messageCenter.OnGatewayConnectionClosed();
            }
        }
예제 #4
0
        protected override async Task RunInternal()
        {
            Exception error = default;

            try
            {
                if (this.connectionOptions.ProtocolVersion == NetworkProtocolVersion.Version1)
                {
                    // This version of the protocol does not support symmetric preamble, so either send or receive preamble depending on
                    // Whether or not this is an inbound or outbound connection.
                    if (this.RemoteSiloAddress is null)
                    {
                        // Inbound connection
                        var protocolVersion = await ReadPreamble();

                        // To support graceful transition to higher protocol versions, send a preamble if the remote endpoint supports it.
                        if (protocolVersion >= NetworkProtocolVersion.Version2)
                        {
                            await WritePreamble();
                        }
                    }
                    else
                    {
                        // Outbound connection
                        await WritePreamble();
                    }
                }
                else
                {
                    // Later versions of the protocol send and receive preamble at both ends of the connection.
                    if (this.RemoteSiloAddress is null)
                    {
                        // Inbound connection
                        var protocolVersion = await ReadPreamble();

                        // To support graceful transition from lower protocol versions, only send a preamble if the remote endpoint supports it.
                        if (protocolVersion >= NetworkProtocolVersion.Version2)
                        {
                            await WritePreamble();
                        }
                    }
                    else
                    {
                        // Outbound connection
                        await Task.WhenAll(ReadPreamble().AsTask(), WritePreamble());
                    }
                }

                this.MessageReceivedCounter = MessagingStatisticsGroup.GetMessageReceivedCounter(this.RemoteSiloAddress);
                this.MessageSentCounter     = MessagingStatisticsGroup.GetMessageSendCounter(this.RemoteSiloAddress);
                await base.RunInternal();
            }
            catch (Exception exception) when((error = exception) is null)
            {
                Debug.Fail("Execution should not be able to reach this point.");
            }
            finally
            {
                if (!(this.RemoteSiloAddress is null))
                {
                    this.connectionManager.OnConnectionTerminated(this.RemoteSiloAddress, this, error);
                }
            }

            async Task WritePreamble()
            {
                await connectionPreambleHelper.Write(
                    this.Context,
                    new ConnectionPreamble
                {
                    NodeIdentity           = Constants.SiloDirectConnectionId,
                    NetworkProtocolVersion = this.connectionOptions.ProtocolVersion,
                    SiloAddress            = this.LocalSiloAddress
                });
            }

            async ValueTask <NetworkProtocolVersion> ReadPreamble()
            {
                var preamble = await connectionPreambleHelper.Read(this.Context);

                if (!preamble.NodeIdentity.Equals(Constants.SiloDirectConnectionId))
                {
                    throw new InvalidOperationException("Unexpected non-proxied connection on silo endpoint.");
                }

                if (preamble.SiloAddress is object)
                {
                    this.RemoteSiloAddress = preamble.SiloAddress;
                    this.connectionManager.OnConnected(preamble.SiloAddress, this);
                }

                this.RemoteProtocolVersion = preamble.NetworkProtocolVersion;

                return(this.RemoteProtocolVersion);
            }
        }