Skip to content

Commit

Permalink
No commit message
Browse files Browse the repository at this point in the history
  • Loading branch information
2 parents bd7071d + 7408283 commit e86c9e9
Show file tree
Hide file tree
Showing 27 changed files with 194 additions and 90 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- os: windows-latest
target-framework: net6.0
- os: windows-latest
target-framework: net461
target-framework: net462
runs-on: ${{ matrix.os }}
env:
TEST_AUTH_TOKEN: ${{ secrets.ALPHA_TEST_AUTH_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/on-push-to-main-branch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
- os: ubuntu-latest
target-framework: net6.0
- os: windows-latest
target-framework: net461
target-framework: net462
runs-on: ${{ matrix.os }}
env:
TEST_AUTH_TOKEN: ${{ secrets.ALPHA_TEST_AUTH_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ test-net6:
.PHONY: test-net-framework
## Run unit and integration tests on the .NET Framework runtime
test-net-framework:
@dotnet test -f net461
@dotnet test -f net462


.PHONY: run-examples
Expand Down
9 changes: 4 additions & 5 deletions src/Momento.Sdk/CacheClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ private ScsDataClient DataClient
protected readonly IConfiguration config;
/// <inheritdoc cref="Microsoft.Extensions.Logging.ILogger" />
protected readonly ILogger _logger;

/// <summary>
/// Async factory function to construct a Momento CacheClient with an eager connection to the
/// Momento server. Calling the CacheClient constructor directly will not establish a connection
Expand Down Expand Up @@ -66,10 +66,9 @@ public static async Task<ICacheClient> CreateAsync(IConfiguration config, ICrede
public CacheClient(IConfiguration config, ICredentialProvider authProvider, TimeSpan defaultTtl)
{
this.config = config;
var _loggerFactory = config.LoggerFactory;
this._logger = _loggerFactory.CreateLogger<CacheClient>();
this._logger = config.LoggerFactory.CreateLogger<CacheClient>();
Utils.ArgumentStrictlyPositive(defaultTtl, "defaultTtl");
this.controlClient = new(_loggerFactory, authProvider.AuthToken, authProvider.ControlEndpoint);
this.controlClient = new(config, authProvider.AuthToken, authProvider.ControlEndpoint);
this.dataClients = new List<ScsDataClient>();
int minNumGrpcChannels = this.config.TransportStrategy.GrpcConfig.MinNumGrpcChannels;
int currentMaxConcurrentRequests = this.config.TransportStrategy.MaxConcurrentRequests;
Expand Down Expand Up @@ -995,7 +994,7 @@ public async Task<CacheSetFetchResponse> SetFetchAsync(string cacheName, string

return await this.DataClient.SetFetchAsync(cacheName, setName);
}

/// <inheritdoc />
public async Task<CacheSetSampleResponse> SetSampleAsync(string cacheName, string setName, int limit)
{
Expand Down
6 changes: 6 additions & 0 deletions src/Momento.Sdk/Config/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ public IConfiguration WithTransportStrategy(ITransportStrategy transportStrategy
return new Configuration(LoggerFactory, RetryStrategy, Middlewares, transportStrategy);
}

/// <inheritdoc />
public IConfiguration WithSocketsHttpHandlerOptions(SocketsHttpHandlerOptions options)
{
return new Configuration(LoggerFactory, RetryStrategy, Middlewares, TransportStrategy.WithSocketsHttpHandlerOptions(options));
}

/// <summary>
/// Add the specified middlewares to an existing instance of Configuration object in addition to already specified middlewares.
/// </summary>
Expand Down
13 changes: 12 additions & 1 deletion src/Momento.Sdk/Config/Configurations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,25 @@ private Lambda(ILoggerFactory loggerFactory, IRetryStrategy retryStrategy, ITran

}

/// <summary>
/// Provides the latest recommended configuration for a lambda environment.
/// </summary>
/// <param name="loggerFactory"></param>
/// <returns></returns>
public static IConfiguration V1(ILoggerFactory? loggerFactory = null)
{
return Default.V1(loggerFactory).WithSocketsHttpHandlerOptions(
SocketsHttpHandlerOptions.Of(pooledConnectionIdleTimeout: TimeSpan.FromMinutes(6)));
}

/// <summary>
/// Provides the latest recommended configuration for a lambda environment.
/// </summary>
/// <param name="loggerFactory"></param>
/// <returns></returns>
public static IConfiguration Latest(ILoggerFactory? loggerFactory = null)
{
return Default.V1(loggerFactory);
return V1(loggerFactory);
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/Momento.Sdk/Config/IConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ public interface IConfiguration
/// <returns>Configuration object with custom transport strategy provided</returns>
public IConfiguration WithTransportStrategy(ITransportStrategy transportStrategy);

/// <summary>
/// Creates a new instance of the Configuration object, updated to use the specified SocketHttpHandler options.
/// </summary>
/// <param name="options">Customizations to the SocketsHttpHandler</param>
/// <returns></returns>
public IConfiguration WithSocketsHttpHandlerOptions(SocketsHttpHandlerOptions options);

/// <summary>
/// Creates a new instance of the Configuration object, updated to use the specified client timeout.
/// </summary>
Expand Down
16 changes: 16 additions & 0 deletions src/Momento.Sdk/Config/Transport/IGrpcConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ public interface IGrpcConfiguration
/// </summary>
public GrpcChannelOptions GrpcChannelOptions { get; }

/// <summary>
/// Override the SocketsHttpHandler's options.
/// This is irrelevant if the client is using the web client or the HttpClient (older .NET runtimes).
/// </summary>
/// <remarks>
/// This is not part of the gRPC config because it is not part of <see cref="GrpcChannelOptions"/>.
/// </remarks>
public SocketsHttpHandlerOptions SocketsHttpHandlerOptions { get; }

/// <summary>
/// Copy constructor to override the Deadline
/// </summary>
Expand All @@ -54,4 +63,11 @@ public interface IGrpcConfiguration
/// <param name="grpcChannelOptions"></param>
/// <returns>A new IGrpcConfiguration with the specified channel options</returns>
public IGrpcConfiguration WithGrpcChannelOptions(GrpcChannelOptions grpcChannelOptions);

/// <summary>
/// Copy constructor to override the SocketsHttpHandler's options.
/// </summary>
/// <param name="idleTimeout"></param>
/// <returns></returns>
public IGrpcConfiguration WithSocketsHttpHandlerOptions(SocketsHttpHandlerOptions idleTimeout);
}
7 changes: 7 additions & 0 deletions src/Momento.Sdk/Config/Transport/ITransportStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ public interface ITransportStrategy
/// <returns>A new ITransportStrategy with the specified grpcConfig</returns>
public ITransportStrategy WithGrpcConfig(IGrpcConfiguration grpcConfig);

/// <summary>
/// Copy constructor to update the SocketsHttpHandler's options
/// </summary>
/// <param name="options"></param>
/// <returns></returns>
public ITransportStrategy WithSocketsHttpHandlerOptions(SocketsHttpHandlerOptions options);

/// <summary>
/// Copy constructor to update the client timeout
/// </summary>
Expand Down
66 changes: 66 additions & 0 deletions src/Momento.Sdk/Config/Transport/SocketsHttpHandlerOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#pragma warning disable 1591
using System;
using Momento.Sdk.Internal;
namespace Momento.Sdk.Config.Transport;

public class SocketsHttpHandlerOptions
{
public static TimeSpan DefaultPooledConnectionIdleTimeout { get; } = TimeSpan.FromMinutes(1);
public TimeSpan PooledConnectionIdleTimeout { get; } = DefaultPooledConnectionIdleTimeout;
public bool EnableMultipleHttp2Connections { get; } = true;

public SocketsHttpHandlerOptions() { }
public SocketsHttpHandlerOptions(TimeSpan pooledConnectionIdleTimeout) : this(pooledConnectionIdleTimeout, true) { }
public SocketsHttpHandlerOptions(bool enableMultipleHttp2Connections) : this(DefaultPooledConnectionIdleTimeout, enableMultipleHttp2Connections) { }

public SocketsHttpHandlerOptions(TimeSpan pooledConnectionIdleTimeout, bool enableMultipleHttp2Connections)
{
Utils.ArgumentStrictlyPositive(pooledConnectionIdleTimeout, nameof(pooledConnectionIdleTimeout));
PooledConnectionIdleTimeout = pooledConnectionIdleTimeout;
EnableMultipleHttp2Connections = enableMultipleHttp2Connections;
}

public SocketsHttpHandlerOptions WithPooledConnectionIdleTimeout(TimeSpan pooledConnectionIdleTimeout)
{
return new SocketsHttpHandlerOptions(pooledConnectionIdleTimeout, EnableMultipleHttp2Connections);
}

public SocketsHttpHandlerOptions WithEnableMultipleHttp2Connections(bool enableMultipleHttp2Connections)
{
return new SocketsHttpHandlerOptions(PooledConnectionIdleTimeout, enableMultipleHttp2Connections);
}

public static SocketsHttpHandlerOptions Of(TimeSpan pooledConnectionIdleTimeout)
{
return new SocketsHttpHandlerOptions(pooledConnectionIdleTimeout);
}

public static SocketsHttpHandlerOptions Of(bool enableMultipleHttp2Connections)
{
return new SocketsHttpHandlerOptions(enableMultipleHttp2Connections);
}

public static SocketsHttpHandlerOptions Of(TimeSpan pooledConnectionIdleTimeout, bool enableMultipleHttp2Connections)
{
return new SocketsHttpHandlerOptions(pooledConnectionIdleTimeout, enableMultipleHttp2Connections);
}

public override bool Equals(object obj)

Check warning on line 48 in src/Momento.Sdk/Config/Transport/SocketsHttpHandlerOptions.cs

View workflow job for this annotation

GitHub Actions / publish

Nullability of type of parameter 'obj' doesn't match overridden member (possibly because of nullability attributes).
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}

var other = (SocketsHttpHandlerOptions)obj;
return PooledConnectionIdleTimeout.Equals(other.PooledConnectionIdleTimeout) &&
EnableMultipleHttp2Connections.Equals(other.EnableMultipleHttp2Connections);
}

public override int GetHashCode()
{
return PooledConnectionIdleTimeout.GetHashCode() * 17 + EnableMultipleHttp2Connections.GetHashCode();
}


}
27 changes: 22 additions & 5 deletions src/Momento.Sdk/Config/Transport/StaticTransportStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,37 +17,47 @@ public class StaticGrpcConfiguration : IGrpcConfiguration
public int MinNumGrpcChannels { get; }
/// <inheritdoc/>
public GrpcChannelOptions GrpcChannelOptions { get; }
/// <inheritdoc/>
public SocketsHttpHandlerOptions SocketsHttpHandlerOptions { get; }

/// <summary>
///
/// </summary>
/// <param name="deadline">Maximum amount of time before a request will timeout</param>
/// <param name="grpcChannelOptions">Customizations to low-level gRPC channel configuration</param>
/// <param name="minNumGrpcChannels">minimum number of gRPC channels to open</param>
public StaticGrpcConfiguration(TimeSpan deadline, GrpcChannelOptions? grpcChannelOptions = null, int minNumGrpcChannels = 1)
/// <param name="socketsHttpHandlerOptions">Customizations to the SocketsHttpHandler</param>
public StaticGrpcConfiguration(TimeSpan deadline, GrpcChannelOptions? grpcChannelOptions = null, int minNumGrpcChannels = 1, SocketsHttpHandlerOptions? socketsHttpHandlerOptions = null)
{
Utils.ArgumentStrictlyPositive(deadline, nameof(deadline));
this.Deadline = deadline;
this.MinNumGrpcChannels = minNumGrpcChannels;
this.GrpcChannelOptions = grpcChannelOptions ?? new GrpcChannelOptions();
this.SocketsHttpHandlerOptions = socketsHttpHandlerOptions ?? new SocketsHttpHandlerOptions();
}

/// <inheritdoc/>
public IGrpcConfiguration WithDeadline(TimeSpan deadline)
{
return new StaticGrpcConfiguration(deadline, this.GrpcChannelOptions, this.MinNumGrpcChannels);
return new StaticGrpcConfiguration(deadline, GrpcChannelOptions, MinNumGrpcChannels, SocketsHttpHandlerOptions);
}

/// <inheritdoc/>
public IGrpcConfiguration WithMinNumGrpcChannels(int minNumGrpcChannels)
{
return new StaticGrpcConfiguration(this.Deadline, this.GrpcChannelOptions, minNumGrpcChannels);
return new StaticGrpcConfiguration(Deadline, GrpcChannelOptions, minNumGrpcChannels, SocketsHttpHandlerOptions);
}

/// <inheritdoc/>
public IGrpcConfiguration WithGrpcChannelOptions(GrpcChannelOptions grpcChannelOptions)
{
return new StaticGrpcConfiguration(this.Deadline, grpcChannelOptions, this.MinNumGrpcChannels);
return new StaticGrpcConfiguration(Deadline, grpcChannelOptions, MinNumGrpcChannels);
}

/// <inheritdoc/>
public IGrpcConfiguration WithSocketsHttpHandlerOptions(SocketsHttpHandlerOptions options)
{
return new StaticGrpcConfiguration(Deadline, GrpcChannelOptions, MinNumGrpcChannels, options);
}

/// <inheritdoc />
Expand All @@ -61,7 +71,8 @@ public override bool Equals(object obj)
var other = (StaticGrpcConfiguration)obj;

return Deadline.Equals(other.Deadline) &&
MinNumGrpcChannels == other.MinNumGrpcChannels;
MinNumGrpcChannels == other.MinNumGrpcChannels &&
SocketsHttpHandlerOptions.Equals(other.SocketsHttpHandlerOptions);
// TODO: gRPC doesn't implement a to equals for this
//GrpcChannelOptions.Equals(other.GrpcChannelOptions);
}
Expand Down Expand Up @@ -121,6 +132,12 @@ public ITransportStrategy WithGrpcConfig(IGrpcConfiguration grpcConfig)
return new StaticTransportStrategy(_loggerFactory, MaxConcurrentRequests, grpcConfig);
}

/// <inheritdoc />
public ITransportStrategy WithSocketsHttpHandlerOptions(SocketsHttpHandlerOptions options)
{
return new StaticTransportStrategy(_loggerFactory, MaxConcurrentRequests, GrpcConfig.WithSocketsHttpHandlerOptions(options));
}

/// <inheritdoc/>
public ITransportStrategy WithClientTimeout(TimeSpan clientTimeout)
{
Expand Down
5 changes: 1 addition & 4 deletions src/Momento.Sdk/ITopicClient.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
#if NETSTANDARD2_0_OR_GREATER


using System.Threading.Tasks;
using Momento.Sdk.Responses;
Expand Down Expand Up @@ -36,7 +34,7 @@ public interface ITopicClient : IDisposable
/// </code>
/// </returns>
public Task<TopicPublishResponse> PublishAsync(string cacheName, string topicName, byte[] value);

/// <inheritdoc cref="PublishAsync(string, string, byte[])"/>
public Task<TopicPublishResponse> PublishAsync(string cacheName, string topicName, string value);

Expand Down Expand Up @@ -66,4 +64,3 @@ public interface ITopicClient : IDisposable
/// </returns>
public Task<TopicSubscribeResponse> SubscribeAsync(string cacheName, string topicName, ulong? resumeAtSequenceNumber = null);
}
#endif
20 changes: 13 additions & 7 deletions src/Momento.Sdk/Internal/ControlGrpcManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
using System.Threading.Tasks;
using Grpc.Core;
using Grpc.Net.Client;
#if USE_GRPC_WEB
using System.Net.Http;
#if USE_GRPC_WEB
using Grpc.Net.Client.Web;
#endif
using Microsoft.Extensions.Logging;
using Momento.Protos.ControlClient;
using Momento.Sdk.Config;
using Momento.Sdk.Config.Middleware;
using Momento.Sdk.Internal.Middleware;
using static System.Reflection.Assembly;
Expand Down Expand Up @@ -86,8 +87,9 @@ internal sealed class ControlGrpcManager : IDisposable
private readonly string runtimeVersion = $"{moniker}:{System.Environment.Version}";
private readonly ILogger _logger;

public ControlGrpcManager(ILoggerFactory loggerFactory, string authToken, string endpoint)
public ControlGrpcManager(IConfiguration config, string authToken, string endpoint)
{
this._logger = config.LoggerFactory.CreateLogger<ControlGrpcManager>();
#if USE_GRPC_WEB
// Note: all web SDK requests are routed to a `web.` subdomain to allow us flexibility on the server
endpoint = $"web.{endpoint}";
Expand All @@ -98,20 +100,24 @@ public ControlGrpcManager(ILoggerFactory loggerFactory, string authToken, string
Credentials = ChannelCredentials.SecureSsl,
MaxReceiveMessageSize = Internal.Utils.DEFAULT_MAX_MESSAGE_SIZE,
MaxSendMessageSize = Internal.Utils.DEFAULT_MAX_MESSAGE_SIZE,
#if USE_GRPC_WEB
HttpHandler = new GrpcWebHandler(new HttpClientHandler()),
#if NET5_0_OR_GREATER
HttpHandler = new System.Net.Http.SocketsHttpHandler
{
EnableMultipleHttp2Connections = config.TransportStrategy.GrpcConfig.SocketsHttpHandlerOptions.EnableMultipleHttp2Connections,
PooledConnectionIdleTimeout = config.TransportStrategy.GrpcConfig.SocketsHttpHandlerOptions.PooledConnectionIdleTimeout
}
#elif USE_GRPC_WEB
HttpHandler = new GrpcWebHandler(new HttpClientHandler())
#endif
});
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) };
CallInvoker invoker = this.channel.CreateCallInvoker();

var middlewares = new List<IMiddleware> {
new HeaderMiddleware(loggerFactory, headers)
new HeaderMiddleware(config.LoggerFactory, headers)
};

Client = new ControlClientWithMiddleware(new ScsControl.ScsControlClient(invoker), middlewares);

this._logger = loggerFactory.CreateLogger<ControlGrpcManager>();
}

public void Dispose()
Expand Down
Loading

0 comments on commit e86c9e9

Please sign in to comment.