-
Notifications
You must be signed in to change notification settings - Fork 10.2k
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
Add support for Output Caching #27387
Comments
Thanks for contacting us. |
Recently I was asked to add response caching in our netcoreapp3.1 microservices using Redis as storage, and find out that there is no extension point to extend the ResponseCachingMiddleware behavior (changing storage, actually), and all similar issues links to this one. What ResponseCachingMiddleware has (which we wouldn't want to duplicate) is:
What ResponseCachingMiddleware should allow to do is (IMHO):
So, my suggestions are follows:
I couldn't see the benefit you gain if you write brand new middleware. |
I can't judge whether these features should be added to the existing response cache library or whether it should be a separate library.
|
I needed to disable caching when some data are added for some admin profiles. Searched all around and finally was directed to this post. Would appreciate this future to be implemented asap. |
@rahou25 This should be controllable by just setting the appropriate HTTP headers. If that is not sufficient, you can also just add the Response Caching Middleware conditionally using |
FYI/FWIW, @madskristensen has a package that looks like it's doing Output Caching in the traditional sense. Looks like it's depending on MVC though, which I imagine wouldn't be a goal of a new middleware. And I'm not sure how compatible it is beyond ASP.NET Core 2 without giving that a go. He did push an update 17 days ago though, so perhaps he's got some thoughts. |
@benmccallum Nice find! 😄
Actually, in the repo readme it states one can use it also in other stacks:
(bold is mine for emphasis). Additionally, found another implementation that may achieve the same effect: (haven't tested it myself) Mentioned by author in SO response: |
Those all take a dependency on MVC though, (at least I think Pages does and MVC/webapi are the same thing in core). I guess what I meant is that output caching will likely function void of any of that, e.g. based only on middleware so it could cache the result of a middleware that's an inline delegate for all it knows! We'll see what the team would come up with, but that'd be great for custom middleware that doesn't need all the MVC stuff, like writing a robots.txt for instance :) |
Yeah anything we would do would be decoupled from MVC/WebAPI/Razor Pages (yes they're all the same thing) and operate at the middleware/request pipeline level. We'd very likely provide mechanisms to provide metadata that controls the behavior for specific resources from within the context of MVC assets though, similar to what we do today for CORS and authorization, e.g. |
Take a look at https://github.com/thepirat000/CachingFramework.Redis, it allows specifying tags, so you can invalidate cache by tag. I have two attributes, first to store and read from cache, second to invalidate the cache. sample usage:
|
Is the |
We are planning on shipping this feature as part of .NET 7. I'll update this thread next week with some initial thoughts in order to gather feedback and contributions. |
@sebastienros I built an internal prototype middleware, mostly based on the new This prototyped is tied to "OData", but could be generalized, of course. |
@StefanOverHaevgRZ thanks. Happy to use your brain and @martincostello 's (though he might have more than one). |
Here is an update with a broad list of features that could be implemented. They won't probably be all be done by RTM, but still listed. It also needs to be prioritized and some design discussions are much needed. Feel free to mention what you think is required by your scenarios and what is non-blocking if not implemented. I don't think it's missing any feature that were discussed here or in other places. Feature currently discussed"Optional": means a feature that can be enabled or disabled. Whether the feature should be enabled or disabled by default is open to discussion. Declarative configurationDeclaratively configure Razor Pages or controller actions for caching. Imperative configurationDefine the caching configuration of specific endpoints by code. Force caching statusThe developer has a way to force a response to be cached/not-cached or a cache entry to be bypassed, overriding any decision made by the service. Vary cache by custom valuesCache entries can vary by common value like scheme, hostname, path, query, or any custom property, e.g., culture, region, tenant ... Optionally cache authenticated contentWhen enabled, authenticated content should be cached. Cached entries can vary by user or roles. Optionally cache cookies and headersBased on allow-lists, some requests can be cached even if cookies are set. When configured, cookies and headers can be cached with the content. Optional lockingWhen locking is configured, a single request processes a specific resource. If other requests query the same resource, they will be queued. See cache stampede and thundering herd topics for more details. Optional stale cacheWhen the server returns an error, or a lock is acquired on this resource, the cache can return a stale entry depending on a timeout (grace period). Optional Etag supportWhen configured, an Etag header will be generated for each response. If the "If-None-Match" header is defined, a 304 response is returned. When not configured, Etag values are not generated and the "If-None-Match" header is ignored. Etags might be generated on further requests only, to optimize for the first response (pass-through response writing without beffurization). Optional cache re-validationWhen an entry is stale and refreshed, if "If-Modified-Since" or "If-None-Match" are set, and the content is identical a 304 will be returned and the cached entry refreshed. TaggingCached entries can be tagged with custom values to be evicted in group. Usages: invalidate cached entries for a specific user, tenant, culture, path, file type, ... PurgeCached entries can be purged using a service. No default remote support is provided, and each application can define secure endpoints to allow for purging entries remotely. However specific store implementation can also have some logic to purge entries overtime based on usage and quotas. StoresIn-memory, filesystem, and hybrid stores (metadata in memory and content on disk) are planned. Some stores should be able to handle size limits. Custom storageThe storage for cached entries can be extended by developers by implementing a service and registering it in DI. Potential implementations: Redis, database, CosmosDB, table/blob storage, sqlite Optional Antiforegy Token substitutionWhen configured, AFTs can be extracted from the response and replaced every time a cached entry is returned. This allows pages using forms to be cached. The feature could be generalized to allow for injecting custom fragments in cached results and enable doughnut caching. Optional byte-range cachingWhen configured, byte-range requests can be cached and/or served from cached entries. DiagnosticsLogging will provide information on when a cache entry is created or served. Features which won't be implemented directly but can be added by third-partiesCache warmup and external computationExternal processes can periodically query the site to warmup specific resources in cache. Delayed cachingCache the resource when it has been accessed a specific number of times. |
Epic created |
Will it support donut caching? See https://www.devtrends.co.uk/blog/donut-output-caching-in-asp.net-mvc-3 for more information regarding ASP.NET (not core). |
@nfplee The plan by @sebastienros above mentions:
So it sounds like: yes, if the team sees enough interest to make that generalization a priority. I agree with the article you linked to that without it, many sites would be prevented from using output caching in the first place. Antiforgery tokens being automatically inserted into many forms by tag helpers, this scenario is even more widespread, so I can't imagine that they would build output caching but miss out on this feature. |
I haven't gone through your article yet but I want to reassure you that I am definitely intending to see how we could implement what you need. Thanks for sharing. |
Output caching was merged and will be in .NET 7 Preview 6: #41037 Not all the features mentioned here have made it in yet, but please try it out and file new issues with feedback/suggestions. |
Closing this issue since the feature has shipped. |
Summary
Response caching is wrong, we wrote response caching people want output caching. We sniff headers when app want to say cache/nocache regardless of headers.
It’s less customizable now that pubternal is gone
People with more context
@halter73, @Tratcher, @JunTaoLuo, @DamianEdwards
Motivation and goals
The existing response cache was designed to implement standard HTTP caching semantics. E.g. it cached based on HTTP cache headers like a proxy would (and may be useful in YARP). It also honors the client's request cache headers like using no-cache to bypass the cache.
An output cache is a different beast. Rather than checking HTTP cache headers to decide what should and should not be cached, the decision is instead made directly by the application, likely with a new request Feature, attributes, HttpResponse extension methods, etc. This cache also does not honor any request cache headers from the client. The client isn't supposed to know it's receiving a cached response.
We should create a new caching middleware that's explicitly designed for output caching. Leave the old one alone, it's fine for what it was designed for, but it doesn't cover the output cache scenarios. Trying to combine the two would just get messy, better to have a clean distinction. Note we can probably copy some of the infrastructure from the existing middleware around intercepting responses and storing them, but the public surface area will be fairly different.
There was one output caching style feature that was added to the response caching middleware later, that should be copied/moved(?). It's the VaryByQueryKeys feature on
ResponseCachingFeature
.In scope
A list of major scenarios, perhaps in priority order.
Out of scope
Scenarios you explicitly want to exclude.
Risks / unknowns
How might developers misinterpret/misuse this? How might implementing it restrict us from other enhancements in the future? Also list any perf/security/correctness concerns.
Examples
Give brief examples of possible developer experiences (e.g., code they would write).
Don't be deeply concerned with how it would be implemented yet. Your examples could even be from other technology stacks.
The text was updated successfully, but these errors were encountered: