{"id":24116042,"url":"https://github.com/wivuu/wivuu.globalcache","last_synced_at":"2025-04-05T06:20:40.266Z","repository":{"id":48127752,"uuid":"273550473","full_name":"wivuu/Wivuu.GlobalCache","owner":"wivuu","description":"Wivuu.GlobalCache library providing a cheap and effortless way to host a distributed access caching mechanism","archived":false,"fork":false,"pushed_at":"2024-07-09T21:18:31.000Z","size":191,"stargazers_count":1,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-11T21:05:27.231Z","etag":null,"topics":["azure","caching","csharp","dotnet"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wivuu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-06-19T17:26:01.000Z","updated_at":"2023-05-08T01:35:09.000Z","dependencies_parsed_at":"2022-08-12T19:10:45.938Z","dependency_job_id":null,"html_url":"https://github.com/wivuu/Wivuu.GlobalCache","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wivuu%2FWivuu.GlobalCache","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wivuu%2FWivuu.GlobalCache/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wivuu%2FWivuu.GlobalCache/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wivuu%2FWivuu.GlobalCache/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wivuu","download_url":"https://codeload.github.com/wivuu/Wivuu.GlobalCache/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247295560,"owners_count":20915523,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["azure","caching","csharp","dotnet"],"created_at":"2025-01-11T06:15:07.192Z","updated_at":"2025-04-05T06:20:40.217Z","avatar_url":"https://github.com/wivuu.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Wivuu.GlobalCache\n[![Nuget](https://github.com/wivuu/Wivuu.GlobalCache/workflows/Nuget/badge.svg)](https://github.com/wivuu/Wivuu.GlobalCache/actions?query=workflow%3ANuget)\n\n[![wivuu.globalcache](https://img.shields.io/nuget/v/wivuu.globalcache.svg?label=wivuu.globalcache)](https://www.nuget.org/packages/Wivuu.GlobalCache/)\n[![wivuu.globalcache.AzureStorage](https://img.shields.io/nuget/v/wivuu.globalcache.azurestorage.svg?label=wivuu.globalcache.azurestorage)](https://www.nuget.org/packages/Wivuu.GlobalCache.AzureStorage)\n[![wivuu.globalcache.BinarySerializer](https://img.shields.io/nuget/v/wivuu.globalcache.binaryserializer.svg?label=wivuu.globalcache.binaryserializer)](https://www.nuget.org/packages/Wivuu.GlobalCache.BinarySerializer)\n\n\nThe GlobalCache library endeavors to provide a cheap and effortless way to host a distributed caching mechanism.\n\nThis is a great fit if:\n- You want to keep costs down by avoiding use of VMs or services like Redis.\n- The API surface area is sufficient for your needs (GetOrCreate and Invalidate).\n- You write to/update a datasource infrequently, but querying and aggregating data out is common and CPU/memory/database intensive; simply call `InvalidateAsync` on the cache whenever a write happens and then `GetOrCreate` in the distributed consumer so that the aggregation logic only happens once per write.\n\n![](images/2020-06-25-10-24-55.png)\n\n*The above sample demonstrates pulling data from the database and processing it (above the red line) vs. downloading pre-cached 100kb from premium blob storage (below the red line)*\n\n## Progress\n- [View board](https://github.com/wivuu/Wivuu.GlobalCache/projects/1)\n- [View issues](https://github.com/wivuu/Wivuu.GlobalCache/issues)\n\n## Azure Blob Storage\nUsing azure blob storage provider you can utilize Premium Block Blob to get consistent low latency, datacenter local cache that can be shared across many instances of your application or even by Azure Functions. You can configure Lifecycle Management on your container to automatically expire categories of cached item and detect changes to your cache using the change feed or azure function blob triggers. \n\n## Installation\n\nThis library can be installed via NuGet:\n\n```sh\n# Install the core library; includes filesystem adapter \u0026 JSON serializer\ndotnet add package Wivuu.GlobalCache \n\n# Or install the azure storage adapter directly\ndotnet add package Wivuu.GlobalCache.AzureStorage # Install Azure Storage adapter\ndotnet add package Wivuu.GlobalCache.BinarySerializer # Optionally: Install Binary Serialization adapter\ndotnet add package Wivuu.GlobalCache.Web # Optionally: Install ASP.NET globalcache attribute\n```\n\n## Usage with DependencyInjection\n\nUsing standard Microsoft DI, GlobalCache can be included in your `Startup.cs`\n\n```C#\nusing Wivuu.GlobalCache;\nusing Wivuu.GlobalCache.AzureStorage;\nusing Wivuu.GlobalCache.BinarySerializer;\n\npublic void ConfigureServices(IServiceCollection collection)\n{\n    // ...\n\n    // Adds with default settings\n    collection.AddWivuuGlobalCache();\n\n    // OR configure additional settings\n    collection.AddWivuuGlobalCache(options =\u003e\n    {\n        // Use local storage emulator \n        var blobServiceClient = new BlobServiceClient(\"UseDevelopmentStorage=true\");\n        var container         = blobServiceClient.GetBlobContainerClient(\"globalcache\");\n\n        // Create a storage container if it doesnt exist\n        container.CreateIfNotExists();\n\n        // Use blob storage provider\n        options.StorageProvider = new BlobStorageProvider(container);\n\n        // Use binary serialization provider\n        options.SerializationProvider = new BinarySerializationProvider();\n    });\n}\n```\n\n## Usage with DI\n\nOnce the global cache has been configured, it can be included using standard DI\n\n```C#\n[HttpGet]\npublic async Task\u003cActionResult\u003cstring\u003e\u003e GetExpensiveItemAsync([FromServices]IGlobalCache cache, \n                                                              [FromQuery]string name) =\u003e\n    // If the result is already cached, it will retrieve the cached value, otherwise\n    // the (potentially expensive) provided generator function will be invoked and then the\n    // result will be stored for future use\n    await cache.GetOrCreateAsync(new CacheId(\"expensiveitems\", name), async () =\u003e\n    {\n        // Simulate hard work!\n        await Task.Delay(5_000);\n\n        // Or, you know, retrieve 1,000,000 items from a database and execute\n        // expensive aggregation formulas no the resulting data and return it.\n\n        return $\"Hello {name}!\";\n    });\n\n[HttpPut]\npublic async Task PutInvalidationAsync([FromServices]IGlobalCache cache) =\u003e\n    // Invalidate all names stored in the cache\n    await cache.InvalidateAsync(CacheId.ForCategory(\"expensiveitems\"));\n```\n\n## Using the GlobalCache attribute with ASP.NET Core\n\nThe easiest way to use Wivuu GlobalCache with ASP.NET is with the `GlobalCache` attribute. \nThe attribute contains several options for specifying which cached item to pull, such as varying by parameters, headers, or by your own custom logic (by implementing `IGlobalCacheExpiration`). You can also set a duration on the attribute which floors the current date by your specified duration, so if you want requests to get updated information every hour, you would use `3600` seconds, and a new cache key would be generated every hour your action is requested.\n\n### How it works\nThe `GlobalCache` works by adding a `IAsyncActionFilter` which generates a predictable cache id inside your `category`, based on the request parameters, route, and attribute settings, then it attempts to open up a read stream to the cached location. If that cached response is not found, it execute your action as normal and append an HTTP Context item for later in the pipeline. Otherwise it will send the cached response back.\n\nThe `GlobalCache` attribute additionally implements the `IAsyncResultFilter` which checks if a cache id is present in the HTTP context; if it is it will intercept your actions response stream and multiplex it to the client AND to the cache backing storage.\n\n### Install the package\n\n```\ndotnet add package Wivuu.GlobalCache.Web\n```\n\nOnce the package is installed, and the service is configured in your Startup.cs, simply add the attribute to your actions, like below.\n\n```C#\n[HttpGet]\n[GlobalCache(\"weather/byday/{days}\")] // Replace variable in path\n// [GlobalCache(\"weather/byday\", VaryByParam=\"days\")] // Or generate unique hash based on days\npublic async Task\u003cIList\u003cWeatherItem\u003e\u003e GetAsync([FromQuery]int days = 100)\n{\n    var start  = DateTime.Now.AddDays(-days);\n    var report = await MyWeatherAPI.GetWeatherSinceAsync(start);\n\n    return report;\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwivuu%2Fwivuu.globalcache","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwivuu%2Fwivuu.globalcache","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwivuu%2Fwivuu.globalcache/lists"}