Skip to content

Commit

Permalink
No commit message
Browse files Browse the repository at this point in the history
  • Loading branch information
2 parents fc65ed9 + d1fd4da commit c555be1
Show file tree
Hide file tree
Showing 26 changed files with 752 additions and 250 deletions.
35 changes: 25 additions & 10 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@ jobs:
dotnet-version: "6.0.x"

- name: Verify README generation
uses: momentohq/standards-and-practices/github-actions/oss-readme-template@gh-actions-v1
uses: momentohq/standards-and-practices/github-actions/oss-readme-template@gh-actions-v2
with:
project_status: official
project_stability: stable
project_type: sdk
sdk_language: .NET
usage_example_path: ./examples/MomentoUsage/Program.cs
template_file: ./README.template.md
output_file: ./README.md
dev_docs_slug: dotnet

- name: Commitlint and Other Shared Build Steps
uses: momentohq/standards-and-practices/github-actions/shared-build@gh-actions-v1
Expand Down Expand Up @@ -68,22 +70,35 @@ jobs:
with:
dotnet-version: "6.0.x"

- name: Run samples
id: validation
- name: Run MomentoApplication example
id: validation-momentoapplication
continue-on-error: true
working-directory: ./examples/MomentoApplication
run: dotnet run

- name: Run doc API snippets
id: validation-docexampleapis
continue-on-error: true
working-directory: ./examples/DocExampleApis
run: dotnet run

- name: Test example failure
id: test-example-failure
run: |
pushd examples
dotnet build MomentoApplication
dotnet run --project MomentoApplication
popd
if [[ "${{ steps.validation-momentoapplication.outcome }}" == "failure" || "${{ steps.validation-docexampleapis.outcome }}" == "failure" ]]
then
echo "failure=true" >> $GITHUB_OUTPUT
else
echo "failure=false" >> $GITHUB_OUTPUT
fi
- name: Send CI failure mail
if: ${{ steps.validation.outcome == 'failure' }}
if: ${{ steps.test-example-failure.outputs.failure == 'true' }}
uses: momentohq/standards-and-practices/github-actions/error-email-action@gh-actions-v1
with:
username: ${{secrets.MOMENTO_ROBOT_GMAIL_USERNAME}}
password: ${{secrets.MOMENTO_ROBOT_GMAIL_PASSWORD}}

- name: Flag Job Failure
if: ${{ steps.validation.outcome == 'failure' }}
if: ${{ steps.test-example-failure.outputs.failure == 'true' }}
run: exit 1
6 changes: 4 additions & 2 deletions .github/workflows/on-push-to-main-branch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@ jobs:
run: dotnet test -f ${{ matrix.target-framework }} tests/Integration/Momento.Sdk.Tests

- name: Generate README
uses: momentohq/standards-and-practices/github-actions/generate-and-commit-oss-readme@gh-actions-v1
uses: momentohq/standards-and-practices/github-actions/generate-and-commit-oss-readme@gh-actions-v2
with:
project_status: official
project_stability: stable
project_type: sdk
sdk_language: .NET
usage_example_path: ./examples/MomentoUsage/Program.cs
template_file: ./README.template.md
output_file: ./README.md
dev_docs_slug: dotnet
12 changes: 6 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
TODO: add more info here.
# Running tests

To run unit tests:
Unless you are testing older .NET runtimes on Windows, you should run the tests against the newer runtimes as follows:

```
dotnet test tests/Unit/Momento.Sdk.Tests
make test-net6
```

To run integration tests:
To test against older .NET runtimes run:

```
dotnet test tests/Integration/Momento.Sdk.Tests
make test-net-framework
```

To run specific tests:

```
dotnet test --filter "FullyQualifiedName~CacheDataTest"
dotnet test -f net6.0 --filter "FullyQualifiedName~CacheDataTest"
```
18 changes: 18 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,24 @@ test:
@dotnet test


.PHONY: test-net6
## Run unit and integration tests on the .NET 6.0 runtime
test-net6:
@dotnet test -f net6.0


.PHONY: test-net-framework
## Run unit and integration tests on the .NET Framework runtime
test-net-framework:
@dotnet test -f net461


.PHONY: run-examples
## Run example applications and snippets
run-examples:
@dotnet run --project examples/MomentoApplication
@dotnet run --project examples/DocExampleApis

# See <https://gist.github.com/klmr/575726c7e05d8780505a> for explanation.
.PHONY: help
help:
Expand Down
130 changes: 19 additions & 111 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,68 +1,29 @@
<head>
<meta name="Momento .NET Client Library Documentation" content=".NET client software development kit for Momento Serverless Cache">
<meta name="Momento .NET Client Library Documentation" content=".NET client software development kit for Momento Cache">
</head>
<img src="https://docs.momentohq.com/img/logo.svg" alt="logo" width="400"/>

[![project status](https://momentohq.github.io/standards-and-practices/badges/project-status-official.svg)](https://github.com/momentohq/standards-and-practices/blob/main/docs/momento-on-github.md)
[![project stability](https://momentohq.github.io/standards-and-practices/badges/project-stability-stable.svg)](https://github.com/momentohq/standards-and-practices/blob/main/docs/momento-on-github.md)
[![project stability](https://momentohq.github.io/standards-and-practices/badges/project-stability-stable.svg)](https://github.com/momentohq/standards-and-practices/blob/main/docs/momento-on-github.md)

# Momento .NET Client Library

Momento Cache is a fast, simple, pay-as-you-go caching solution without any of the operational overhead
required by traditional caching solutions. This repo contains the source code for the Momento .NET client library.

.NET client SDK for Momento Serverless Cache: a fast, simple, pay-as-you-go caching solution without
any of the operational overhead required by traditional caching solutions!


* Website: [https://www.gomomento.com/](https://www.gomomento.com/)
* Momento Documentation: [https://docs.momentohq.com/](https://docs.momentohq.com/)
* Getting Started: [https://docs.momentohq.com/getting-started](https://docs.momentohq.com/getting-started)
* .NET SDK Documentation: [https://docs.momentohq.com/develop/sdks/dotnet](https://docs.momentohq.com/develop/sdks/dotnet)
* Discuss: [Momento Discord](https://discord.gg/3HkAKjUZGq)

Japanese: [日本語](README.ja.md)

## Getting Started :running:

### Requirements

You will need the [`dotnet` runtime and command line tools](https://dotnet.microsoft.com/en-us/download). After installing them, you should have the `dotnet` command on your PATH.

**IDE Notes**: You will most likely want an IDE that supports .NET development, such as [Microsoft Visual Studio](https://visualstudio.microsoft.com/vs), [JetBrains Rider](https://www.jetbrains.com/rider/), or [Microsoft Visual Studio Code](https://code.visualstudio.com/).

### Examples

Ready to dive right in? Just check out the [examples](./examples/README.md) directory for complete, working examples of
how to use the SDK.

### Momento Response Types

The return values of the methods on the Momento `CacheClient` class are designed to allow you to use your
IDE to help you easily discover all the possible responses, including errors. We use [pattern matching](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/functional/pattern-matching) to distinguish between different types of responses,
which means that you can get compile-time safety when interacting with the API, rather than having bugs sneak in at runtime.

Here's an example:

```csharp
CacheGetResponse getResponse = await client.GetAsync(CACHE_NAME, KEY);
if (getResponse is CacheGetResponse.Hit hitResponse)
{
Console.WriteLine($"Looked up value: {hitResponse.ValueString}, Stored value: {VALUE}");
}
else if (getResponse is CacheGetResponse.Error getError)
{
Console.WriteLine($"Error getting value: {getError.Message}");
}
```

See the [Error Handling](#error-handling) section below for more details.

### Installation
## Packages

To create a new .NET project and add the Momento client library as a dependency:
The Momento Dotnet SDK package is available on nuget: [momentohq/client-sdk-dotnet](https://www.nuget.org/packages/Momento.Sdk).

```bash
mkdir my-momento-dotnet-project
cd my-momento-dotnet-project
dotnet new console
dotnet add package Momento.Sdk
```

### Usage
## Usage

Here is a quickstart you can use in your own project:

Expand Down Expand Up @@ -113,71 +74,18 @@ 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).

### Error Handling
## Getting Started and Documentation

Error that occur in calls to CacheClient methods are surfaced to developers as part of the return values of
the calls, as opposed to by throwing exceptions. This makes them more visible, and allows your IDE to be more
helpful in ensuring that you've handled the ones you care about. (For more on our philosophy about this, see our
blog post on why [Exceptions are bugs](https://www.gomomento.com/blog/exceptions-are-bugs). And send us any
feedback you have!)
Documentation is available on the [Momento Docs website](https://docs.momentohq.com).

The preferred way of interpreting the return values from CacheClient methods is using [Pattern matching](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/functional/pattern-matching). Here's a quick example:
## Examples

```csharp
CacheGetResponse getResponse = await client.GetAsync(CACHE_NAME, KEY);
if (getResponse is CacheGetResponse.Hit hitResponse)
{
Console.WriteLine($"\nLooked up value: {hitResponse.ValueString}, Stored value: {VALUE}");
} else {
// you can handle other cases via pattern matching in `else if` blocks, or a default case
// via the `else` block. For each return value your IDE should be able to give you code
// completion indicating the other possible types; in this case, `CacheGetResponse.Miss` and
// `CacheGetResponse.Error`.
}
```

Using this approach, you get a type-safe `hitResponse` object in the case of a cache hit. But if the cache read
results in a Miss or an error, you'll also get a type-safe object that you can use to get more info about what happened.

In cases where you get an error response, `Error` types will always include an `ErrorCode` that you can use to check
the error type:

```csharp
CacheGetResponse getResponse = await client.GetAsync(CACHE_NAME, KEY);
if (getResponse is CacheGetResponse.Error errorResponse)
{
if (errorResponse.ErrorCode == MomentoErrorCode.TIMEOUT_ERROR) {
// this would represent a client-side timeout, and you could fall back to your original data source
}
}
```

Note that, outside of CacheClient responses, exceptions can occur and should be handled as usual. For example, trying
to instantiate a CacheClient with an invalid authentication token will result in an IllegalArgumentException being thrown.

### Tuning

Momento client-libraries provide pre-built configuration bundles out-of-the-box. We want to do the hard work of
tuning for different environments for you, so that you can focus on the things that are unique to your business.
(We even have a blog series about it! [Shockingly simple: Cache clients that do the hard work for you](https://www.gomomento.com/blog/shockingly-simple-cache-clients-that-do-the-hard-work-for-you))

You can find the pre-built configurations in our `Configurations` namespace. Some of the pre-built configurations that
you might be interested in:

- `Configurations.Laptop` - this one is a development environment, just for poking around. It has relaxed timeouts
and assumes that your network latencies might be a bit high.
- `Configurations.InRegion.Default` - provides defaults suitable for an environment where your client is running in the same region as the Momento
service. It has more aggressive timeouts and retry behavior than the Laptop config.
- `Configurations.InRegion.LowLatency` - This config prioritizes keeping p99.9 latencies as low as possible, potentially sacrificing
some throughput to achieve this. Use this configuration if the most important factor is to ensure that cache
unavailability doesn't force unacceptably high latencies for your own application.
Ready to dive right in? Just check out the [examples](./examples/README.md) directory for complete, working examples of
how to use the SDK.

We hope that these configurations will meet the needs of most users, but if you find them lacking in any way, please
open a github issue, or contact us at `[email protected]`. We would love to hear about your use case so that we
can fix or extend the pre-built configs to support it.
## Developing

If you do need to customize your configuration beyond what our pre-builts provide, see the
[Advanced Configuration Guide](./docs/advanced-config.md).
If you are interested in contributing to the SDK, please see the [CONTRIBUTING](./CONTRIBUTING.md) docs.

----------------------------------------------------------------------------------------
For more info, visit our website at [https://gomomento.com](https://gomomento.com)!
Loading

0 comments on commit c555be1

Please sign in to comment.