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

Release/v0.25.0 #193

Merged
merged 42 commits into from
Feb 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
3672b68
Better auto-recovery TryDeleteItem()
jodydonetti Dec 8, 2023
fb104ad
Minor updates to GitHub actions
jodydonetti Dec 31, 2023
dfbc902
Update packages
jodydonetti Dec 31, 2023
d083279
Update SourceLink package
jodydonetti Dec 31, 2023
907a979
Minor docs changes
jodydonetti Jan 14, 2024
98dab32
Update packages
jodydonetti Jan 14, 2024
da8256d
Better tests
jodydonetti Jan 14, 2024
015de6a
Update packages
jodydonetti Jan 14, 2024
ed97054
Minor
jodydonetti Jan 14, 2024
54e8f95
Add observability support (activities & metrics)
jodydonetti Jan 14, 2024
50179da
Add OpenTelemetry instrumentation project
jodydonetti Jan 14, 2024
ed96e4b
Add OTEL scenario in the Playground
jodydonetti Jan 14, 2024
5b3eb7a
Minor
jodydonetti Jan 14, 2024
5aa8562
Minor
jodydonetti Jan 14, 2024
b79d20f
Minor
jodydonetti Jan 14, 2024
d8b7e8f
v0.25.0-preview1
jodydonetti Jan 14, 2024
aa35851
Minor
jodydonetti Jan 21, 2024
c5c0126
Minor
jodydonetti Jan 21, 2024
6987010
Added IFusionCacheMemoryLocker and related impl + marked IFusionCache…
jodydonetti Feb 3, 2024
3981674
Update packages refs
jodydonetti Feb 3, 2024
eecfc69
Update packages refs
jodydonetti Feb 3, 2024
ebab412
Minor
jodydonetti Feb 3, 2024
28b866f
Update packages refs + minor stuff
jodydonetti Feb 3, 2024
fe25b87
Update packages refs + minor stuff
jodydonetti Feb 3, 2024
a15a901
Minor
jodydonetti Feb 3, 2024
dc64a2c
Minor
jodydonetti Feb 3, 2024
450b02c
Re-enable the old FusionCache ctor to better support a transition to …
jodydonetti Feb 4, 2024
6afbebe
Add NullMemoryLocker
jodydonetti Feb 4, 2024
72b5de1
Add ChaosMemoryLocker + minor
jodydonetti Feb 4, 2024
50612e2
Better [Obsolete] usage
jodydonetti Feb 4, 2024
ff6b883
Minor
jodydonetti Feb 4, 2024
a36e385
Stuff
jodydonetti Feb 4, 2024
a857f71
Add Scratchpad scenario in the playground
jodydonetti Feb 4, 2024
11cd454
Minor
jodydonetti Feb 4, 2024
a796853
Better OTEL playground scenario
jodydonetti Feb 4, 2024
5c72599
Add OpenTelemetry docs + minor
jodydonetti Feb 4, 2024
ac0cdc0
Add builder tests for memory locker
jodydonetti Feb 4, 2024
3586760
Minor
jodydonetti Feb 4, 2024
718e6ac
Add test to check if StandardMemoryLocker is used by default
jodydonetti Feb 4, 2024
3b43914
Minor
jodydonetti Feb 4, 2024
e81e243
v0.25.0
jodydonetti Feb 4, 2024
d0d4d2e
Merge from main
jodydonetti Feb 4, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
- name: Set up .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: '7.0.x'
dotnet-version: '8.0.x'
- run: dotnet --info
- name: Build solution and run all tests
run: ./build.sh
4 changes: 2 additions & 2 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,5 @@ jobs:

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
#- name: Upload coverage reports to Codecov
# uses: codecov/codecov-action@v3
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1">
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
28 changes: 12 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@

[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
![Nuget](https://img.shields.io/nuget/dt/ZiggyCreatures.FusionCache)
[![Twitter](https://img.shields.io/twitter/url/http/shields.io.svg?style=flat&logo=twitter)](https://twitter.com/intent/tweet?hashtags=fusioncache,caching,cache,dotnet,oss,csharp&text=🚀+FusionCache:+a+new+cache+with+an+optional+2nd+layer+and+some+advanced+features&url=https%3A%2F%2Fgithub.com%2FZiggyCreatures%2FFusionCache&via=jodydonetti)

</div>

| 🙋‍♂️ Updating from before `v0.24.0` ? please [read here](docs/Update_v0_24_0.md). |
|:-------|

### FusionCache is an easy to use, fast and robust cache with advanced resiliency features and an optional distributed 2nd layer.
### FusionCache is an easy to use, fast and robust cache with advanced resiliency features and an optional distributed 2nd level.

It was born after years of dealing with all sorts of different types of caches: memory caching, distributed caching, http caching, CDNs, browser cache, offline cache, you name it. So I've tried to put together these experiences and came up with FusionCache.

Expand Down Expand Up @@ -73,10 +72,11 @@ These are the **key features** of FusionCache:
- [**🦅 Eager Refresh**](docs/EagerRefresh.md): start a non-blocking background refresh before the expiration occurs
- [**🔃 Dependency Injection**](docs/DependencyInjection.md): native support for Dependency Injection, with a nice fluent interface including a Builder support
- [**📛 Named Caches**](docs/NamedCaches.md): easily work with multiple named caches, even if differently configured
- [**🔭 OpenTelemetry**](docs/OpenTelemetry.md): native observability support via OpenTelemetry
- [**📜 Logging**](docs/Logging.md): comprehensive, structured and customizable, via the standard `ILogger` interface
- [**💫 Natively sync/async**](docs/CoreMethods.md): native support for both the synchronous and asynchronous programming model
- [**📞 Events**](docs/Events.md): a comprehensive set of events, both at a high level and at lower levels (memory/distributed)
- [**🧩 Plugins**](docs/Plugins.md): extend FusionCache with additional behavior like adding support for metrics, statistics, etc...
- [**📜 Logging**](docs/Logging.md): comprehensive, structured and customizable, via the standard `ILogger` interface

<details>
<summary>Something more 😏 ?</summary>
Expand All @@ -90,7 +90,6 @@ Also, FusionCache has some nice **additional features**:
- **✅ Null caching**: explicitly supports caching of `null` values differently than "no value". This creates a less ambiguous usage, and typically leads to better performance because it avoids the classic problem of not being able to differentiate between *"the value was not in the cache, go check the database"* and *"the value was in the cache, and it was `null`"*
- **✅ Circuit-breaker**: it is possible to enable a simple circuit-breaker for when the distributed cache or the backplane become temporarily unavailable. This will prevent those components to be hit with an excessive load of requests (that would probably fail anyway) in a problematic moment, so it can gracefully get back on its feet. More advanced scenarios can be covered using a dedicated solution, like <a href="https://github.com/App-vNext/Polly">Polly</a>
- **✅ Dynamic Jittering**: setting `JitterMaxDuration` will add a small randomized extra duration to a cache entry's normal duration. This is useful to prevent variations of the <a href="https://en.wikipedia.org/wiki/Cache_stampede">Cache Stampede problem</a> in a multi-node scenario
- **✅ Hot Swap**: supports thread-safe changes of the entire distributed cache or backplane implementation (add/swap/removal)
- **✅ Cancellation**: every method supports cancellation via the standard `CancellationToken`, so it is easy to cancel an entire pipeline of operation gracefully
- **✅ Code comments**: every property and method is fully documented in code, with useful informations provided via IntelliSense or similar technologies
- **✅ Fully annotated for [nullability](https://docs.microsoft.com/en-us/dotnet/csharp/nullable-references)**: every usage of nullable references has been annotated for a better flow analysis by the compiler
Expand All @@ -105,7 +104,8 @@ Main packages:
| Package Name | Version | Downloads |
|--------------------------------|:---------------:|:---------:|
| [ZiggyCreatures.FusionCache](https://www.nuget.org/packages/ZiggyCreatures.FusionCache/) <br/> The core package | [![NuGet](https://img.shields.io/nuget/v/ZiggyCreatures.FusionCache.svg)](https://www.nuget.org/packages/ZiggyCreatures.FusionCache/) | ![Nuget](https://img.shields.io/nuget/dt/ZiggyCreatures.FusionCache) |
| [ZiggyCreatures.FusionCache.Chaos](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Chaos/) <br/> A package with additional chaos-related utilities and implementations | [![NuGet](https://img.shields.io/nuget/v/ZiggyCreatures.FusionCache.Chaos.svg)](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Chaos/) | ![Nuget](https://img.shields.io/nuget/dt/ZiggyCreatures.FusionCache.Chaos) |
| [ZiggyCreatures.FusionCache.OpenTelemetry](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.OpenTelemetry/) <br/> Adds native support for OpenTelemetry setup | [![NuGet](https://img.shields.io/nuget/v/ZiggyCreatures.FusionCache.OpenTelemetry.svg)](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.OpenTelemetry/) | ![Nuget](https://img.shields.io/nuget/dt/ZiggyCreatures.FusionCache.OpenTelemetry) |
| [ZiggyCreatures.FusionCache.Chaos](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Chaos/) <br/> A package to add some controller chaos, for testing | [![NuGet](https://img.shields.io/nuget/v/ZiggyCreatures.FusionCache.Chaos.svg)](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Chaos/) | ![Nuget](https://img.shields.io/nuget/dt/ZiggyCreatures.FusionCache.Chaos) |

Serializers:

Expand Down Expand Up @@ -273,37 +273,33 @@ When using FusionCache with the [distributed cache](docs/CacheLevels.md), the [b

[![FusionCache Simulator](https://img.youtube.com/vi/6jGX6ePgD3Q/maxresdefault.jpg)](docs/Simulator.md)

## 🆎 Comparison

There are various alternatives out there with different features, different performance characteristics (cpu/memory) and in general a different set of pros/cons.

A [feature comparison](docs/Comparison.md) between existing .NET caching solutions may help you choose which one to use.

## 🧰 Supported Platforms

FusionCache targets `.NET Standard 2.0` so any compatible .NET implementation is fine: this means `.NET Framework` (the old one), `.NET Core 2+` and `.NET 5/6/7/8+` (the new ones), `Mono` 5.4+ and more (see [here](https://docs.microsoft.com/en-us/dotnet/standard/net-standard#net-implementation-support) for a complete rundown).

**NOTE**: if you are running on **.NET Framework 4.6.1** and want to use **.NET Standard** packages Microsoft suggests to upgrade to .NET Framework 4.7.2 or higher (see the [.NET Standard Documentation](https://docs.microsoft.com/en-us/dotnet/standard/net-standard#net-implementation-support)) to avoid some known dependency issues.

## 🖼 Logo
## 🆎 Comparison

There are various alternatives out there with different features, different performance characteristics (cpu/memory) and in general a different set of pros/cons.

The logo is an [original creation](https://dribbble.com/shots/14854206-FusionCache-logo) and is a [sloth](https://en.wikipedia.org/wiki/Sloth) because, you know, speed.
A [feature comparison](docs/Comparison.md) between existing .NET caching solutions may help you choose which one to use.

## 💰 Support

Nothing to do here.

After years of using a lot of open source stuff for free, this is just me trying to give something back to the community.

If you find FusionCache useful please just [**✉ drop me a line**](https://twitter.com/jodydonetti), I would be interested in knowing about your usage.
If you find FusionCache useful just [**✉ drop me a line**](https://twitter.com/jodydonetti), I would be interested in knowing how you're using it.

And if you really want to talk about money, please consider making **❤ a donation to a good cause** of your choosing, and maybe let me know about that.
And if you really want to talk about money, please consider making **❤ a donation to a good cause** of your choosing, and let me know about that.

## 💼 Is it Production Ready :tm: ?
Yes!

Even though the current version is `0.X` for an excess of caution, FusionCache is already used **in production** on multiple **real world projects** happily handling millions of requests per day, or at least these are the projects I'm aware of.

Considering that the FusionCache packages have been downloaded more than **2 million times** (thanks everybody!) it may very well be used even more.
Considering that the FusionCache packages have been downloaded more than **3 million times** (thanks everybody!) it may very well be used even more.

And again, if you are using it please [**✉ drop me a line**](https://twitter.com/jodydonetti), I'd like to know!
9 changes: 8 additions & 1 deletion ZiggyCreatures.FusionCache.sln
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZiggyCreatures.FusionCache.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SerializerPayloadGenerator", "tests\SerializerPayloadGenerator\SerializerPayloadGenerator.csproj", "{5B1AF24E-90FC-4C21-AF9C-090FE32027E3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZiggyCreatures.FusionCache.Simulator", "tests\ZiggyCreatures.FusionCache.Simulator\ZiggyCreatures.FusionCache.Simulator.csproj", "{BDB46997-84D1-4CB5-B967-7F820820CB8E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZiggyCreatures.FusionCache.Simulator", "tests\ZiggyCreatures.FusionCache.Simulator\ZiggyCreatures.FusionCache.Simulator.csproj", "{BDB46997-84D1-4CB5-B967-7F820820CB8E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZiggyCreatures.FusionCache.OpenTelemetry", "src\ZiggyCreatures.FusionCache.OpenTelemetry\ZiggyCreatures.FusionCache.OpenTelemetry.csproj", "{DA78EB72-93B1-4A77-8525-79AF3EEC4C8D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -111,6 +113,10 @@ Global
{BDB46997-84D1-4CB5-B967-7F820820CB8E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BDB46997-84D1-4CB5-B967-7F820820CB8E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BDB46997-84D1-4CB5-B967-7F820820CB8E}.Release|Any CPU.Build.0 = Release|Any CPU
{DA78EB72-93B1-4A77-8525-79AF3EEC4C8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DA78EB72-93B1-4A77-8525-79AF3EEC4C8D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DA78EB72-93B1-4A77-8525-79AF3EEC4C8D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DA78EB72-93B1-4A77-8525-79AF3EEC4C8D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -131,6 +137,7 @@ Global
{CE437FB2-510F-4DCE-8A1F-AED747DAA4EB} = {34B53F49-F5C5-4850-B79E-59AD130379C6}
{5B1AF24E-90FC-4C21-AF9C-090FE32027E3} = {C6F3C570-C68C-4A95-960E-82778306BDBA}
{BDB46997-84D1-4CB5-B967-7F820820CB8E} = {C6F3C570-C68C-4A95-960E-82778306BDBA}
{DA78EB72-93B1-4A77-8525-79AF3EEC4C8D} = {34B53F49-F5C5-4850-B79E-59AD130379C6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {92916FA2-FCAC-406E-BF3F-0A2CE9512EF0}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using System;
using System.Diagnostics.CodeAnalysis;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Columns;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;
using FastCache;
using LazyCache;
using Microsoft.Extensions.Caching.Memory;

namespace ZiggyCreatures.Caching.Fusion.Benchmarks
{
[RankColumn]
[MemoryDiagnoser]
[Config(typeof(Config))]
[ShortRunJob(RuntimeMoniker.Net60)]
[ShortRunJob(RuntimeMoniker.Net80)]
[Orderer(BenchmarkDotNet.Order.SummaryOrderPolicy.FastestToSlowest)]
public class HappyPathBenchmark
{
private class Config : ManualConfig
{
public Config()
{
AddColumn(
StatisticColumn.P95
);
}
}

const string Key = "test key";
const string Value = "test value";

readonly FusionCache FusionCache = new(new FusionCacheOptions());
readonly MemoryCache MemoryCache = new(new MemoryCacheOptions());
readonly CachingService LazyCache = new();

[GlobalSetup]
public void Setup()
{
FusionCache.Set(Key, Value);
MemoryCache.Set(Key, Value);
LazyCache.Add(Key, Value);
Cached<string>.Save(Key, Value, TimeSpan.FromDays(1));
}

public class HappyPathReads : HappyPathBenchmark
{
[Benchmark(Baseline = true)]
public string? GetFusionCache()
{
return FusionCache.TryGet<string?>(Key)
.GetValueOrDefault(null);
}

[Benchmark]
public string? GetMemoryCache()
{
return MemoryCache.TryGetValue<string?>(Key, out var value)
? value
: Unreachable();
}

[Benchmark]
public string? GetLazyCache()
{
return LazyCache.TryGetValue<string?>(Key, out var value)
? value
: Unreachable();
}

[Benchmark]
public string? GetFastCache()
{
return Cached<string?>.TryGet(Key, out var value)
? value
: Unreachable();
}
}

public class HappyPathWrites : HappyPathBenchmark
{
[Benchmark(Baseline = true)]
public void SetFusionCache() => FusionCache.Set(Key, Value);

[Benchmark]
public void SetMemoryCache() => MemoryCache.Set(Key, Value);

[Benchmark]
public void SetLazyCache() => LazyCache.Add(Key, Value);

[Benchmark]
public void SetFastCache() => Cached<string>.Save(Key, Value, TimeSpan.FromDays(1));
}

[DoesNotReturn]
static string Unreachable() => throw new Exception("Unreachable code");
}
}
Loading
Loading