Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: wire up grpc settings from Configuration #192

Merged
merged 1 commit into from
Sep 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/Momento.Sdk/Config/Configurations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public static Laptop Latest
IRetryStrategy retryStrategy = new FixedCountRetryStrategy(maxAttempts: 3);
ITransportStrategy transportStrategy = new StaticTransportStrategy(
maxConcurrentRequests: 200,
grpcConfig: new StaticGrpcConfiguration(numChannels: 6, maxSessionMemory: 128, useLocalSubChannelPool: true, deadlineMilliseconds: 5000));
grpcConfig: new StaticGrpcConfiguration(deadlineMilliseconds: 5000));
return new Laptop(retryStrategy, transportStrategy);
}
}
Expand Down Expand Up @@ -59,7 +59,7 @@ public static Default Latest
ITransportStrategy transportStrategy = new StaticTransportStrategy(
maxConcurrentRequests: 1,
// TODO: tune the timeout value
grpcConfig: new StaticGrpcConfiguration(numChannels: 6, maxSessionMemory: 128, useLocalSubChannelPool: true, deadlineMilliseconds: 1000));
grpcConfig: new StaticGrpcConfiguration(deadlineMilliseconds: 1000));
return new Default(retryStrategy, transportStrategy);
}
}
Expand Down Expand Up @@ -87,7 +87,7 @@ public static LowLatency Latest
ITransportStrategy transportStrategy = new StaticTransportStrategy(
maxConcurrentRequests: 200,
// TODO: tune the timeout value
grpcConfig: new StaticGrpcConfiguration(numChannels: 6, maxSessionMemory: 128, useLocalSubChannelPool: true, deadlineMilliseconds: 1000)
grpcConfig: new StaticGrpcConfiguration(deadlineMilliseconds: 1000)
);
return new LowLatency(retryStrategy, transportStrategy);
}
Expand Down
24 changes: 6 additions & 18 deletions src/Momento.Sdk/Config/Transport/IGrpcConfiguration.cs
Original file line number Diff line number Diff line change
@@ -1,37 +1,25 @@
using System.Collections.Generic;
using Grpc.Net.Client;

namespace Momento.Sdk.Config.Transport;

/// <summary>
/// Abstracts away the gRPC configuration tunables.
///
/// <see cref="IGrpcConfiguration.MaxSessionMemory" /> and <see cref="IGrpcConfiguration.UseLocalSubChannelPool" /> expose individual settings for gRPC channels. They are just here to ensure that
/// strategy implementations provide values for settings that we know to be important. These may vary by language
/// since the gRPC implementations in each language have subtly different behaviors.
/// </summary>
public interface IGrpcConfiguration
{
public int NumChannels { get; }

public int MaxSessionMemory { get; }
public bool UseLocalSubChannelPool { get; }

/// <summary>
/// How long the client is willing to wait for an RPC to complete before it is terminated with <see cref="Grpc.Core.StatusCode.DeadlineExceeded"/>
/// </summary>
public uint DeadlineMilliseconds { get; }

/// <summary>
/// This is a dictionary that encapsulates the settings above, and may also include other channel-specific settings.
/// This allows strategy implementations to provide gRPC config key/value pairs for any available setting, even
/// if it's not one we've explicitly tried / recommended. The strategy implementation should implement this by
/// calling the functions above, along with allowing a mechanism for specifying additional key/value pairs.
/// Override the default .NET GrpcChannelOptions. (.NET only povides a strongly-typed
/// interface for the channel options, which allows modifying specific values but does
/// not allow the caller to use arbitrary strings to set the channel options.)
/// </summary>
public IDictionary<string, string> GrpcChannelConfig { get; }
public GrpcChannelOptions GrpcChannelOptions { get; }

public IGrpcConfiguration WithNumChannels(int numChannels);
public IGrpcConfiguration WithMaxSessionMemory(int maxSessionMemory);
public IGrpcConfiguration WithUseLocalSubChannelPool(bool useLocalSubChannelPool);
public IGrpcConfiguration WithDeadlineMilliseconds(uint deadlineMilliseconds);
public IGrpcConfiguration WithGrpcChannelConfig(IDictionary<string, string> grpcChannelConfig);
public IGrpcConfiguration WithGrpcChannelOptions(GrpcChannelOptions grpcChannelOptions);
}
44 changes: 8 additions & 36 deletions src/Momento.Sdk/Config/Transport/StaticTransportStrategy.cs
Original file line number Diff line number Diff line change
@@ -1,60 +1,32 @@
using System;
using System.Collections.Generic;
using Momento.Sdk.Internal.ExtensionMethods;
using Grpc.Net.Client;

namespace Momento.Sdk.Config.Transport;


public class StaticGrpcConfiguration : IGrpcConfiguration
{
public int NumChannels { get; }

public int MaxSessionMemory { get; }
public bool UseLocalSubChannelPool { get; }
public uint DeadlineMilliseconds { get; }
public GrpcChannelOptions GrpcChannelOptions { get; }

public IDictionary<string, string> GrpcChannelConfig { get; }

public StaticGrpcConfiguration(int numChannels, int maxSessionMemory, bool useLocalSubChannelPool, uint deadlineMilliseconds, IDictionary<string, string> grpcChannelConfig)
public StaticGrpcConfiguration(uint deadlineMilliseconds, GrpcChannelOptions? grpcChannelOptions = null)
{
this.NumChannels = numChannels;
this.MaxSessionMemory = maxSessionMemory;
this.UseLocalSubChannelPool = useLocalSubChannelPool;

if (deadlineMilliseconds <= 0)
{
throw new ArgumentException($"Deadline must be strictly positive. Value was: {deadlineMilliseconds}", "DeadlineMilliseconds");
}
this.DeadlineMilliseconds = deadlineMilliseconds;
this.GrpcChannelConfig = grpcChannelConfig;
}

public StaticGrpcConfiguration(int numChannels, int maxSessionMemory, bool useLocalSubChannelPool, uint deadlineMilliseconds)
: this(numChannels, maxSessionMemory, useLocalSubChannelPool, deadlineMilliseconds, new Dictionary<string, string>())
{

this.GrpcChannelOptions = grpcChannelOptions ?? new GrpcChannelOptions();
}

public IGrpcConfiguration WithNumChannels(int numChannels)
{
return new StaticGrpcConfiguration(numChannels, MaxSessionMemory, UseLocalSubChannelPool, DeadlineMilliseconds, GrpcChannelConfig.Clone());
}

public IGrpcConfiguration WithMaxSessionMemory(int maxSessionMemory)
{
return new StaticGrpcConfiguration(NumChannels, maxSessionMemory, UseLocalSubChannelPool, DeadlineMilliseconds, GrpcChannelConfig.Clone());
}
public IGrpcConfiguration WithUseLocalSubChannelPool(bool useLocalSubChannelPool)
{
return new StaticGrpcConfiguration(NumChannels, MaxSessionMemory, useLocalSubChannelPool, DeadlineMilliseconds, GrpcChannelConfig.Clone());
}
public IGrpcConfiguration WithDeadlineMilliseconds(uint deadlineMilliseconds)
{
return new StaticGrpcConfiguration(NumChannels, MaxSessionMemory, UseLocalSubChannelPool, deadlineMilliseconds, GrpcChannelConfig.Clone());
return new StaticGrpcConfiguration(deadlineMilliseconds, this.GrpcChannelOptions);
}
public IGrpcConfiguration WithGrpcChannelConfig(IDictionary<string, string> grpcChannelConfig)

public IGrpcConfiguration WithGrpcChannelOptions(GrpcChannelOptions grpcChannelOptions)
{
return new StaticGrpcConfiguration(NumChannels, MaxSessionMemory, UseLocalSubChannelPool, DeadlineMilliseconds, grpcChannelConfig);
return new StaticGrpcConfiguration(this.DeadlineMilliseconds, grpcChannelOptions);
}
}

Expand Down
9 changes: 6 additions & 3 deletions src/Momento.Sdk/Internal/DataGrpcManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,19 @@ public class DataGrpcManager : IDisposable

public readonly IDataClient Client;

private readonly string version = "dotnet:" + GetAssembly(typeof(Momento.Sdk.Responses.CacheGetResponse)).GetName().Version.ToString();
private readonly string version = "dotnet:" + GetAssembly(typeof(Responses.CacheGetResponse)).GetName().Version.ToString();
// Some System.Environment.Version remarks to be aware of
// https://learn.microsoft.com/en-us/dotnet/api/system.environment.version?view=netstandard-2.0#remarks
private readonly string runtimeVersion = "dotnet:" + System.Environment.Version;
private readonly string runtimeVersion = "dotnet:" + Environment.Version;
private readonly ILogger _logger;

internal DataGrpcManager(IConfiguration config, string authToken, string host, ILoggerFactory? loggerFactory = null)
{
var url = $"https://{host}";
this.channel = GrpcChannel.ForAddress(url, new GrpcChannelOptions() { Credentials = ChannelCredentials.SecureSsl });
var channelOptions = config.TransportStrategy.GrpcConfig.GrpcChannelOptions;
channelOptions.Credentials = ChannelCredentials.SecureSsl;

this.channel = GrpcChannel.ForAddress(url, channelOptions);
List<Header> headers = new List<Header> { new Header(name: Header.AuthorizationKey, value: authToken), new Header(name: Header.AgentKey, value: version), new Header(name: Header.RuntimeVersionKey, value: runtimeVersion) };
this._logger = Utils.CreateOrNullLogger<DataGrpcManager>(loggerFactory);
CallInvoker invoker = this.channel.Intercept(new HeaderInterceptor(headers));
Expand Down
2 changes: 0 additions & 2 deletions src/Momento.Sdk/Internal/ScsDataClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
using Microsoft.Extensions.Logging;
using Momento.Protos.CacheClient;
using Momento.Sdk.Config;
using Momento.Sdk.Config.Middleware;
using Momento.Sdk.Exceptions;
using Momento.Sdk.Internal;
using Momento.Sdk.Internal.ExtensionMethods;
using Momento.Sdk.Responses;

Expand Down
2 changes: 1 addition & 1 deletion tests/Unit/Momento.Sdk.Tests/ConfigTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ public class ConfigTest
[Fact]
public void StaticGrpcConfiguration_BadDeadline_ThrowsException()
{
Assert.Throws<ArgumentException>(() => new StaticGrpcConfiguration(5, 128, true, 0));
Assert.Throws<ArgumentException>(() => new StaticGrpcConfiguration(0));
}
}