protected override async Task RunInternal()
        {
            var(grainId, protocolVersion, siloAddress) = await ConnectionPreamble.Read(this.Context);

            if (protocolVersion >= NetworkProtocolVersion.Version2)
            {
                await ConnectionPreamble.Write(
                    this.Context,
                    Constants.SiloDirectConnectionId,
                    this.connectionOptions.ProtocolVersion,
                    this.myAddress);
            }

            if (grainId.Equals(Constants.SiloDirectConnectionId))
            {
                throw new InvalidOperationException($"Unexpected direct silo connection on proxy endpoint from {siloAddress?.ToString() ?? "unknown silo"}");
            }

            try
            {
                this.gateway.RecordOpenedConnection(this, grainId);
                await base.RunInternal();
            }
            finally
            {
                this.gateway.RecordClosedConnection(this);
            }
        }
        protected override async Task RunInternal()
        {
            try
            {
                this.messageCenter.OnGatewayConnectionOpen();

                await ConnectionPreamble.Write(
                    this.Context,
                    this.messageCenter.ClientId,
                    this.connectionOptions.ProtocolVersion,
                    siloAddress : null);

                if (this.connectionOptions.ProtocolVersion >= NetworkProtocolVersion.Version2)
                {
                    var(_, protocolVersion, siloAddress) = await ConnectionPreamble.Read(this.Context);

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

                await base.RunInternal();
            }
            finally
            {
                this.connectionManager.OnConnectionTerminated(this.RemoteSiloAddress, this);
                this.messageCenter.OnGatewayConnectionClosed();
            }
        }
Example #3
0
        protected override async Task RunInternal()
        {
            try
            {
                await Task.WhenAll(ReadPreamble(), WritePreamble());

                await base.RunInternal();
            }
            finally
            {
                if (!(this.remoteSiloAddress is null))
                {
                    this.connectionManager.OnConnectionTerminated(this.remoteSiloAddress, this);
                }
            }

            Task WritePreamble() => ConnectionPreamble.Write(this.Context, Constants.SiloDirectConnectionId, this.myAddress);

            async Task ReadPreamble()
            {
                var(grainId, siloAddress) = await ConnectionPreamble.Read(this.Context);

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

                if (siloAddress != null)
                {
                    this.remoteSiloAddress = siloAddress;
                    this.connectionManager.OnConnected(siloAddress, this);
                }
            }
        }
Example #4
0
        internal async ValueTask Write(ConnectionContext connection, ConnectionPreamble preamble)
        {
            var output = connection.Transport.Output;

            using var outputWriter = new PrefixingBufferWriter <byte, PipeWriter>(sizeof(int), 1024, MemoryPool <byte> .Shared);
            outputWriter.Reset(output);
            _preambleSerializer.Serialize(
                preamble,
                outputWriter);

            var length = outputWriter.CommittedBytes;

            if (length > MaxPreambleLength)
            {
                throw new InvalidOperationException($"Created preamble of length {length}, which is greater than maximum allowed size of {MaxPreambleLength}.");
            }

            WriteLength(outputWriter, length);

            var flushResult = await output.FlushAsync();

            if (flushResult.IsCanceled)
            {
                throw new OperationCanceledException("Flush canceled");
            }

            return;
        }
Example #5
0
        protected override async Task RunInternal()
        {
            var(grainId, protocolVersion, siloAddress) = await ConnectionPreamble.Read(this.Context);

            if (protocolVersion >= NetworkProtocolVersion.Version2)
            {
                await ConnectionPreamble.Write(
                    this.Context,
                    Constants.SiloDirectConnectionId,
                    this.connectionOptions.ProtocolVersion,
                    this.myAddress);
            }

            if (grainId.Equals(Constants.SiloDirectConnectionId))
            {
                throw new InvalidOperationException($"Unexpected direct silo connection on proxy endpoint from {siloAddress?.ToString() ?? "unknown silo"}");
            }

            // refuse clients that are connecting to the wrong cluster
            if (grainId.Category == UniqueKey.Category.GeoClient)
            {
                if (grainId.Key.ClusterId != this.siloDetails.ClusterId)
                {
                    var message = string.Format(
                        "Refusing connection by client {0} because of cluster id mismatch: client={1} silo={2}",
                        grainId, grainId.Key.ClusterId, this.siloDetails.ClusterId);
                    this.Log.Error(ErrorCode.GatewayAcceptor_WrongClusterId, message);
                    throw new InvalidOperationException(message);
                }
            }
            else
            {
                //convert handshake cliendId to a GeoClient ID
                if (this.multiClusterOptions.HasMultiClusterNetwork)
                {
                    grainId = GrainId.NewClientId(grainId.PrimaryKey, this.siloDetails.ClusterId);
                }
            }

            try
            {
                this.gateway.RecordOpenedConnection(this, grainId);
                await base.RunInternal();
            }
            finally
            {
                this.gateway.RecordClosedConnection(this);
            }
        }
Example #6
0
        protected override async Task RunInternal()
        {
            try
            {
                this.messageCenter.OnGatewayConnectionOpen();

                await ConnectionPreamble.Write(this.Context, this.messageCenter.ClientId, siloAddress : null);

                await base.RunInternal();
            }
            finally
            {
                if (this.TargetSilo != null)
                {
                    this.gatewayManager.MarkAsDead(this.TargetSilo);
                }
                this.messageCenter.OnGatewayConnectionClosed();
            }
        }
Example #7
0
        protected override async Task RunInternal()
        {
            Exception error = default;

            try
            {
                this.messageCenter.OnGatewayConnectionOpen();

                await ConnectionPreamble.Write(
                    this.Context,
                    this.messageCenter.ClientId,
                    this.connectionOptions.ProtocolVersion,
                    siloAddress : null);

                if (this.connectionOptions.ProtocolVersion >= NetworkProtocolVersion.Version2)
                {
                    var(_, protocolVersion, siloAddress) = await ConnectionPreamble.Read(this.Context);

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

                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();
            }
        }
Example #8
0
        protected override async Task RunInternal()
        {
            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());
                    }
                }

                await base.RunInternal();
            }
            finally
            {
                if (!(this.RemoteSiloAddress is null))
                {
                    this.connectionManager.OnConnectionTerminated(this.RemoteSiloAddress, this);
                }
            }

            async Task WritePreamble()
            {
                await ConnectionPreamble.Write(
                    this.Context,
                    Constants.SiloDirectConnectionId,
                    this.connectionOptions.ProtocolVersion,
                    this.LocalSiloAddress);
            }

            async ValueTask <NetworkProtocolVersion> ReadPreamble()
            {
                var(grainId, protocolVersion, siloAddress) = await ConnectionPreamble.Read(this.Context);

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

                if (siloAddress != null)
                {
                    this.RemoteSiloAddress = siloAddress;
                    this.connectionManager.OnConnected(siloAddress, this);
                }

                return(protocolVersion);
            }
        }
Example #9
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 ConnectionPreamble.Write(
                    this.Context,
                    Constants.SiloDirectConnectionId,
                    this.connectionOptions.ProtocolVersion,
                    this.LocalSiloAddress);
            }

            async ValueTask <NetworkProtocolVersion> ReadPreamble()
            {
                var(grainId, protocolVersion, siloAddress) = await ConnectionPreamble.Read(this.Context);

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

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

                this.RemoteProtocolVersion = protocolVersion;

                return(protocolVersion);
            }
        }