Tyto.Rpc.Caching
0.1.0-alpha.2
See the version list below for details.
dotnet add package Tyto.Rpc.Caching --version 0.1.0-alpha.2
NuGet\Install-Package Tyto.Rpc.Caching -Version 0.1.0-alpha.2
<PackageReference Include="Tyto.Rpc.Caching" Version="0.1.0-alpha.2" />
<PackageVersion Include="Tyto.Rpc.Caching" Version="0.1.0-alpha.2" />
<PackageReference Include="Tyto.Rpc.Caching" />
paket add Tyto.Rpc.Caching --version 0.1.0-alpha.2
#r "nuget: Tyto.Rpc.Caching, 0.1.0-alpha.2"
#:package Tyto.Rpc.Caching@0.1.0-alpha.2
#addin nuget:?package=Tyto.Rpc.Caching&version=0.1.0-alpha.2&prerelease
#tool nuget:?package=Tyto.Rpc.Caching&version=0.1.0-alpha.2&prerelease
Tyto.Rpc.Caching
Caches the answers of RPC calls, without the request contracts knowing anything about it.
tyto.AddRpc(rpc => rpc.AddClient(client => client
.UseInProcess(...)
.UseCaching(caching => {
caching.For<GetCategoriesRpcRequest, GetCategoriesRpcResponse>("categories", policy => policy
.WithKey(request => request.AppId.ToString())
.WithTtl(TimeSpan.FromMinutes(15))
.WithStaleWhileRevalidate(TimeSpan.FromMinutes(13)));
caching.For<ValidateAppAccessRpcRequest, ValidateAppAccessRpcResponse>("app-access", policy => policy
.WithKey(request => $"{request.OrganizationId}:{request.AppId}:{request.ClientId}")
.WithTtl(TimeSpan.FromMinutes(30))
.WithTags("app-access")
.CacheErrors<NotFoundError>());
})));
A key is required
WithKey must name everything that can change the answer. A field left out of the key is a field
whose value the first caller decides for everyone — a request that asked about one channel filling
the entry every later channel then reads. A policy without a key is refused when it is configured.
A request that genuinely has one answer for the whole application says so:
policy.SingleEntry();
There is no default key. There used to be: the request type's name, so forgetting WithKey gave
every request of that type one shared entry and nobody was told.
Cached errors keep their type
CacheErrors<TError>() stores the error with the entry and hands it back as it was:
RpcResult<ProfileResponse> result = await client.CallAsync(new GetProfileRequest(org, user));
// result.Error is NotFoundError { ResourceType = "Recipient", ResourceId = "42" } — from the cache too
Errors used to be stored as "nothing" and served back as a generic not-found about the response type, so the resource and its id were gone and one business error could not be told from another.
Errors the policy does not name — timeouts, unavailable services, transport failures — are never stored; they reach the caller and the next call tries again.
Invalidation
The cache stores a wrapper around the response, so removing an entry does not go through
ICache<string, TResponse>. Use the profile's invalidator, or tags:
await cacheFactory.GetInvalidator("app-access").InvalidateAsync($"{organizationId}:{appId}:{clientId}");
endpoint.InvalidateCache("app-access")
.On<AppCredentialRevokedIntegrationEvent>(e => $"{e.OrganizationId}:{e.AppId}:{e.ClientId}");
What you get from Tyto.Caching
The policy's TTL, sliding expiration, stale-while-revalidate and tags are that library's, and so is
the rest: one factory per key, a cancellation that does not cancel the other callers, a circuit
breaker in front of the distributed layer, and an invalidation that says so when it cannot be
delivered. See src/Caching/README.md.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Tyto.Caching.Abstractions (>= 0.1.0-alpha.2)
- Tyto.Rpc.Abstractions (>= 0.1.0-alpha.2)
- Tyto.Rpc.Client (>= 0.1.0-alpha.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0-alpha.10 | 56 | 10/1/2026 |
| 0.1.0-alpha.9 | 53 | 9/27/2026 |
| 0.1.0-alpha.8 | 56 | 9/26/2026 |
| 0.1.0-alpha.7 | 82 | 9/25/2026 |
| 0.1.0-alpha.6 | 61 | 9/24/2026 |
| 0.1.0-alpha.5 | 112 | 9/21/2026 |
| 0.1.0-alpha.4 | 66 | 9/20/2026 |
| 0.1.0-alpha.3 | 60 | 9/20/2026 |
| 0.1.0-alpha.2 | 55 | 9/20/2026 |
| 0.1.0-alpha.1 | 54 | 9/20/2026 |
| 0.0.1-alpha.106 | 58 | 9/15/2026 |
| 0.0.1-alpha.105 | 116 | 9/14/2026 |
| 0.0.1-alpha.104 | 86 | 9/10/2026 |
| 0.0.1-alpha.103 | 71 | 9/4/2026 |
| 0.0.1-alpha.102 | 66 | 9/1/2026 |
| 0.0.1-alpha.101 | 62 | 9/1/2026 |
| 0.0.1-alpha.100 | 84 | 8/24/2026 |
| 0.0.1-alpha.99 | 74 | 8/20/2026 |
| 0.0.1-alpha.98 | 74 | 8/18/2026 |
| 0.0.1-alpha.97 | 70 | 8/18/2026 |