Skip to content

Commit

Permalink
No commit message
Browse files Browse the repository at this point in the history
  • Loading branch information
2 parents e86c9e9 + 2825ab8 commit 551049a
Show file tree
Hide file tree
Showing 32 changed files with 344 additions and 371 deletions.
11 changes: 7 additions & 4 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ jobs:
build_csharp:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
target-framework: [net6.0]
grpc-web: [false, true]
include:
- os: ubuntu-latest
target-framework: net6.0
- os: windows-latest
target-framework: net6.0
target-framework: net462
grpc-web: false
- os: windows-latest
target-framework: net462
grpc-web: true
runs-on: ${{ matrix.os }}
env:
TEST_AUTH_TOKEN: ${{ secrets.ALPHA_TEST_AUTH_TOKEN }}
Expand Down Expand Up @@ -47,7 +50,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Build
run: dotnet build
run: dotnet build ${{ matrix.grpc-web && '-p:DefineConstants=USE_GRPC_WEB' || '' }}

- name: Unit Test
run: dotnet test --logger "console;verbosity=detailed" -f ${{ matrix.target-framework }} tests/Unit/Momento.Sdk.Tests
Expand Down
11 changes: 8 additions & 3 deletions .github/workflows/on-push-to-main-branch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@ jobs:
build_csharp:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
target-framework: [net6.0]
grpc-web: [false, true]
include:
- os: ubuntu-latest
target-framework: net6.0
- os: windows-latest
target-framework: net462
grpc-web: false
- os: windows-latest
target-framework: net462
grpc-web: true
runs-on: ${{ matrix.os }}
env:
TEST_AUTH_TOKEN: ${{ secrets.ALPHA_TEST_AUTH_TOKEN }}
Expand All @@ -32,7 +37,7 @@ jobs:
dotnet-version: "6.0.x"

- name: Build
run: dotnet build
run: dotnet build ${{ matrix.grpc-web && '-p:DefineConstants=USE_GRPC_WEB' || '' }}

- name: Unit Test
run: dotnet test -f ${{ matrix.target-framework }} tests/Unit/Momento.Sdk.Tests
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ using (ICacheClient client = new CacheClient(Configurations.Laptop.V1(), authPro

```

Note that the above code requires an environment variable named MOMENTO_AUTH_TOKEN which must
be set to a valid [Momento authentication token](https://docs.momentohq.com/docs/getting-started#obtain-an-auth-token).
Note that the above code requires an environment variable named MOMENTO_API_KEY which must
be set to a valid [Momento authentication token](https://docs.momentohq.com/cache/develop/authentication/api-keys).

## Getting Started and Documentation

Expand Down
4 changes: 2 additions & 2 deletions README.template.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ Here is a quickstart you can use in your own project:
{% include "./examples/MomentoUsage/Program.cs" %}
```

Note that the above code requires an environment variable named MOMENTO_AUTH_TOKEN which must
be set to a valid [Momento authentication token](https://docs.momentohq.com/docs/getting-started#obtain-an-auth-token).
Note that the above code requires an environment variable named MOMENTO_API_KEY which must
be set to a valid [Momento authentication token](https://docs.momentohq.com/cache/develop/authentication/api-keys).

## Getting Started and Documentation

Expand Down
4 changes: 2 additions & 2 deletions examples/DictionaryExample/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ This example program demonstrates usage of the dictionary data type.

# Usage

The program assumes the auth token and cache names are available in environment variables. The auth token is assumed to be in the variable `TEST_AUTH_TOKEN` and the cache name in `TEST_CACHE_NAME`. If either of these is missing, you will be prompted to enter the values on the terminal.
The program assumes the auth token and cache names are available in environment variables. The auth token is assumed to be in the variable `MOMENTO_API_KEY` and the cache name in `MOMENTO_CACHE_NAME`. If either of these is missing, you will be prompted to enter the values on the terminal.

To run the program, run either:

```bash
TEST_AUTH_TOKEN=<YOUR_TOKEN_HERE> TEST_CACHE_NAME=<YOUR_CACHE_NAME_HERE> dotnet run
MOMENTO_API_KEY=<YOUR_API_KEY_HERE> MOMENTO_CACHE_NAME=<YOUR_CACHE_NAME_HERE> dotnet run
```

or
Expand Down
2 changes: 1 addition & 1 deletion examples/DisposableTokens/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ This example program demonstrates how to generate disposable Momento auth tokens
The program assumes that your Momento auth token is available in the `MOMENTO_API_KEY` environment variable:

```bash
MOMENTO_API_KEY=<YOUR_AUTH_TOKEN> dotnet run
MOMENTO_API_KEY=<YOUR_API_KEY> dotnet run
```

The example generates a disposable expiring auth token using the enumerated permissions and expiry defined in the program and prints its attributes to the console.
6 changes: 3 additions & 3 deletions examples/MomentoApplication/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,20 @@ functionality, including:
## Prerequisites

* [`dotnet`](https://dotnet.microsoft.com/en-us/download) 6.0 or higher is required
* A Momento auth token is required. You can generate one using the [Momento CLI](https://github.com/momentohq/momento-cli).
* A Momento API key is required. You can generate one using the [Momento Console](https://console.gomomento.com/api-keys).

## Running the application example

Run the following from within the `examples` directory:

```bash
MOMENTO_API_KEY=<YOUR AUTH TOKEN> dotnet run --project MomentoApplication
MOMENTO_API_KEY=<YOUR API KEY> dotnet run --project MomentoApplication
```

Within the `MomentoAppication` directory you can run:

```bash
MOMENTO_API_KEY=<YOUR AUTH TOKEN> dotnet run
MOMENTO_API_KEY=<YOUR API KEY> dotnet run
```

## Error Handling
Expand Down
8 changes: 4 additions & 4 deletions examples/MomentoLoadGen/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,28 @@ If you have questions or need help experimenting further, please reach out to us
## Prerequisites

* [`dotnet`](https://dotnet.microsoft.com/en-us/download) 6.0 or higher is required
* A Momento auth token is required. You can generate one using the [Momento CLI](https://github.com/momentohq/momento-cli).
* A Momento API key is required. You can generate one using the [Momento Console](https://console.gomomento.com/api-keys).

## Running the load generator

To run the load generator (from the `examples` directory):

```bash
# Run example load generator
MOMENTO_API_KEY=<YOUR AUTH TOKEN> dotnet run --project MomentoLoadGen
MOMENTO_API_KEY=<YOUR API KEY> dotnet run --project MomentoLoadGen
```

Within the `MomentoLoadGen` directory you can run:

```bash
# Run example load generator
MOMENTO_API_KEY=<YOUR AUTH TOKEN> dotnet run
MOMENTO_API_KEY=<YOUR API KEY> dotnet run
```

If you make modifications to the code, remember to do a clean otherwise
the program might not run.

```bash
dotnet clean
MOMENTO_API_KEY=<YOUR AUTH TOKEN> dotnet run
MOMENTO_API_KEY=<YOUR API KEY> dotnet run
```
6 changes: 3 additions & 3 deletions examples/MomentoUsage/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,20 @@ the client's full capabilities, take a look at the more advanced [MomentoApplic
## Prerequisites

* [`dotnet`](https://dotnet.microsoft.com/en-us/download) 6.0 or higher is required
* A Momento auth token is required. You can generate one using the [Momento CLI](https://github.com/momentohq/momento-cli).
* A Momento API key is required. You can generate one using the [Momento Console](https://console.gomomento.com/api-keys).

## Running the application example

Run the following from within the `examples` directory:

```bash
MOMENTO_API_KEY=<YOUR AUTH TOKEN> dotnet run --project MomentoUsage
MOMENTO_API_KEY=<YOUR API KEY> dotnet run --project MomentoUsage
```

Within the `MomentoUsage` directory you can run:

```bash
MOMENTO_API_KEY=<YOUR AUTH TOKEN> dotnet run
MOMENTO_API_KEY=<YOUR API KEY> dotnet run
```

## Error Handling
Expand Down
6 changes: 3 additions & 3 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
## Prerequisites

* [`dotnet`](https://dotnet.microsoft.com/en-us/download) 6.0 or higher is required
* A Momento auth token is required. You can generate one using the [Momento CLI](https://github.com/momentohq/momento-cli).
* A Momento API key is required. You can generate one using the [Momento Console](https://console.gomomento.com/api-keys).

## Running the advanced example

To run the advanced example code defined in [`MomentoApplication/Program.cs`](./MomentoApplication/Program.cs),
run the following from within the `examples` directory:

```bash
MOMENTO_AUTH_TOKEN=<YOUR AUTH TOKEN> dotnet run --project MomentoApplication
MOMENTO_API_KEY=<YOUR API KEY> dotnet run --project MomentoApplication
```

## Error Handling
Expand Down Expand Up @@ -82,5 +82,5 @@ To run the load generator (from the `examples` directory):

```bash
# Run example load generator
MOMENTO_AUTH_TOKEN=<YOUR AUTH TOKEN> dotnet run --project MomentoLoadGen
MOMENTO_API_KEY=<YOUR AUTH TOKEN> dotnet run --project MomentoLoadGen
```
4 changes: 2 additions & 2 deletions examples/TopicExample/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ This example program demonstrates usage of Momento Topics.

# Usage

The program assumes the auth token and cache names are available in environment variables. The auth token is assumed to be in the variable `TEST_AUTH_TOKEN` and the cache name in `TEST_CACHE_NAME`. If either of these is missing, you will be prompted to enter the values on the terminal.
The program assumes the auth token and cache names are available in environment variables. The auth token is assumed to be in the variable `MOMENTO_API_KEY` and the cache name in `MOMENTO_CACHE_NAME`. If either of these is missing, you will be prompted to enter the values on the terminal.

To run the program, run either:

```bash
TEST_AUTH_TOKEN=<YOUR_TOKEN_HERE> TEST_CACHE_NAME=<YOUR_CACHE_NAME_HERE> dotnet run
MOMENTO_API_KEY=<YOUR_API_KEY_HERE> MOMENTO_CACHE_NAME=<YOUR_CACHE_NAME_HERE> dotnet run
```

or
Expand Down
6 changes: 0 additions & 6 deletions src/Momento.Sdk/Config/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,6 @@ 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
18 changes: 16 additions & 2 deletions src/Momento.Sdk/Config/Configurations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,11 @@ public static IConfiguration V1(ILoggerFactory? loggerFactory = null)
/// This config optimizes for lambda environments. In addition to the in region settings of
/// <see cref="Default"/>, this configures the clients to eagerly connect to the Momento service
/// to avoid the cold start penalty of establishing a connection on the first request.
/// NOTE: keep-alives are very important for long-lived server environments where there may be periods of time
/// when the connection is idle. However, they are very problematic for lambda environments where the lambda
/// runtime is continuously frozen and unfrozen, because the lambda may be frozen before the "ACK" is received
/// from the server. This can cause the keep-alive to timeout even though the connection is completely healthy.
/// Therefore, keep-alives should be disabled in lambda and similar environments.
/// </summary>
public class Lambda : Configuration
{
Expand All @@ -184,8 +189,17 @@ private Lambda(ILoggerFactory loggerFactory, IRetryStrategy retryStrategy, ITran
/// <returns></returns>
public static IConfiguration V1(ILoggerFactory? loggerFactory = null)
{
return Default.V1(loggerFactory).WithSocketsHttpHandlerOptions(
SocketsHttpHandlerOptions.Of(pooledConnectionIdleTimeout: TimeSpan.FromMinutes(6)));
var config = Default.V1(loggerFactory);
var transportStrategy = config.TransportStrategy.WithSocketsHttpHandlerOptions(
SocketsHttpHandlerOptions.Of(
pooledConnectionIdleTimeout: TimeSpan.FromMinutes(6),
enableMultipleHttp2Connections: true,
keepAlivePingTimeout: System.Threading.Timeout.InfiniteTimeSpan,
keepAlivePingDelay: System.Threading.Timeout.InfiniteTimeSpan,
keepAlivePermitWithoutCalls: false
)
);
return config.WithTransportStrategy(transportStrategy);
}

/// <summary>
Expand Down
7 changes: 0 additions & 7 deletions src/Momento.Sdk/Config/IConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,6 @@ 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
3 changes: 2 additions & 1 deletion src/Momento.Sdk/Config/TopicConfigurations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ public static ITopicConfiguration Latest(ILoggerFactory? loggerFactory = null)
var finalLoggerFactory = loggerFactory ?? NullLoggerFactory.Instance;
ITopicTransportStrategy transportStrategy = new StaticTopicTransportStrategy(
loggerFactory: finalLoggerFactory,
grpcConfig: new StaticGrpcConfiguration(deadline: TimeSpan.FromMilliseconds(1100)));
grpcConfig: new StaticGrpcConfiguration(deadline: TimeSpan.FromMilliseconds(1100))
);
return new Default(finalLoggerFactory, transportStrategy);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,11 @@ public interface IVectorIndexTransportStrategy
/// <param name="clientTimeout"></param>
/// <returns>A new IVectorIndexTransportStrategy with the specified client timeout</returns>
public IVectorIndexTransportStrategy WithClientTimeout(TimeSpan clientTimeout);

/// <summary>
/// Copy constructor to update the SocketsHttpHandler's options
/// </summary>
/// <param name="options"></param>
/// <returns></returns>
public IVectorIndexTransportStrategy WithSocketsHttpHandlerOptions(SocketsHttpHandlerOptions options);
}
63 changes: 63 additions & 0 deletions src/Momento.Sdk/Config/Transport/SocketsHttpHandlerOptions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma warning disable 1591
using System;
using System.Net.Http;
using Momento.Sdk.Internal;
namespace Momento.Sdk.Config.Transport;

Expand All @@ -9,6 +10,36 @@ public class SocketsHttpHandlerOptions
public TimeSpan PooledConnectionIdleTimeout { get; } = DefaultPooledConnectionIdleTimeout;
public bool EnableMultipleHttp2Connections { get; } = true;

/// <summary>
/// Override the time to wait for a response from a keepalive or ping.
/// NOTE: keep-alives are very important for long-lived server environments where there may be periods of time
/// when the connection is idle. However, they are very problematic for lambda environments where the lambda
/// runtime is continuously frozen and unfrozen, because the lambda may be frozen before the "ACK" is received
/// from the server. This can cause the keep-alive to timeout even though the connection is completely healthy.
/// Therefore, keep-alives should be disabled in lambda and similar environments.
/// </summary>
public TimeSpan KeepAlivePingTimeout { get; } = TimeSpan.FromMilliseconds(1000);

/// <summary>
/// After a duration of this time the client/server pings its peer to see if the transport is still alive.
/// NOTE: keep-alives are very important for long-lived server environments where there may be periods of time
/// when the connection is idle. However, they are very problematic for lambda environments where the lambda
/// runtime is continuously frozen and unfrozen, because the lambda may be frozen before the "ACK" is received
/// from the server. This can cause the keep-alive to timeout even though the connection is completely healthy.
/// Therefore, keep-alives should be disabled in lambda and similar environments.
/// </summary>
public TimeSpan KeepAlivePingDelay { get; } = TimeSpan.FromMilliseconds(5000);

/// <summary>
/// Indicates if it permissible to send keepalive pings from the client without any outstanding streams.
/// NOTE: keep-alives are very important for long-lived server environments where there may be periods of time
/// when the connection is idle. However, they are very problematic for lambda environments where the lambda
/// runtime is continuously frozen and unfrozen, because the lambda may be frozen before the "ACK" is received
/// from the server. This can cause the keep-alive to timeout even though the connection is completely healthy.
/// Therefore, keep-alives should be disabled in lambda and similar environments.
/// </summary>
public bool KeepAlivePermitWithoutCalls { get; } = true;

public SocketsHttpHandlerOptions() { }
public SocketsHttpHandlerOptions(TimeSpan pooledConnectionIdleTimeout) : this(pooledConnectionIdleTimeout, true) { }
public SocketsHttpHandlerOptions(bool enableMultipleHttp2Connections) : this(DefaultPooledConnectionIdleTimeout, enableMultipleHttp2Connections) { }
Expand All @@ -19,6 +50,21 @@ public SocketsHttpHandlerOptions(TimeSpan pooledConnectionIdleTimeout, bool enab
PooledConnectionIdleTimeout = pooledConnectionIdleTimeout;
EnableMultipleHttp2Connections = enableMultipleHttp2Connections;
}
public SocketsHttpHandlerOptions(
TimeSpan pooledConnectionIdleTimeout,
bool enableMultipleHttp2Connections,
TimeSpan keepAlivePingTimeout,
TimeSpan keepAlivePingDelay,
bool keepAlivePermitWithoutCalls
)
{
Utils.ArgumentStrictlyPositive(pooledConnectionIdleTimeout, nameof(pooledConnectionIdleTimeout));
PooledConnectionIdleTimeout = pooledConnectionIdleTimeout;
EnableMultipleHttp2Connections = enableMultipleHttp2Connections;
KeepAlivePingTimeout = keepAlivePingTimeout;
KeepAlivePingDelay = keepAlivePingDelay;
KeepAlivePermitWithoutCalls = keepAlivePermitWithoutCalls;
}

public SocketsHttpHandlerOptions WithPooledConnectionIdleTimeout(TimeSpan pooledConnectionIdleTimeout)
{
Expand All @@ -45,6 +91,23 @@ public static SocketsHttpHandlerOptions Of(TimeSpan pooledConnectionIdleTimeout,
return new SocketsHttpHandlerOptions(pooledConnectionIdleTimeout, enableMultipleHttp2Connections);
}

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

public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
Expand Down
Loading

0 comments on commit 551049a

Please sign in to comment.