-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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 atomic increment/decrement operations to IDistributedCache #36386
Comments
Ping! |
This seems like a different service than |
You mean because you operate on numbers instead of bytes? I dunno, it's pretty common to cache "counters" like this. |
When I think distributed caching, I don't think of atomicity. What you are describing sounds more like a distributed semaphore (which consul implements for example), which does seem like it belongs to a separate interface. |
I don't really care where the methods live, I just want to be able to invoke a Redis |
Yeah, fair point. Why not do that rather than wait for an abstraction: var redis = StackExchange.Redis.ConnectionMultiplexer.Connect("localhost");
var db = redis.GetDatabase();
db.*Increment(... You already a transitive dependency on |
Because I'm writing a middleware that I'd like to keep decoupled from Redis. Because ASP.NET Core already has the |
It's not a great fit, at least not for this interface. |
We don't intend to support this behavior in the |
So, for implementing throttling/rate limiting, what kind of service would you recommend I use to store the number of requests for the current IP, without forcing all my users to use Redis? Does it exist? 🤔 This is straight forward with caching primitives for most (other) platforms... |
Can you tell me more about the caching primitives other platforms provide? I'm certainly not opposed to this if there's prior art. Redis has an It sounds like you're basically looking for a "database" (for lack of a better term) here rather than a cache, since you're storing data that you're relying upon. Caches generally are targeted at transient data storage backed up by some underlying store. What would happen to the throttling data when the cache drops your key as part of scavenging/expiration? Redis (as an implementation) is more of a database, so using it directly for this makes some sense, or providing your own abstraction in your middleware component. I'm not necessarily opposed to having an abstraction for this, just trying to understand how this fits into the area of "caching". |
Laravel
RailsHas an abstract cache store class with implementations for in-memory, Memcached and Redis out of the box. Has both an Django
This was just the first three I looked at, in ten minutes on my phone. They're also some of the most popular web frameworks out there. All of them expose increment and decrement operations directly in their caching primitives. The most popular stores like Memcached and Redis support these operations natively.
Why not? 🤔
Yes, tell me about it. It works somewhat, but has no transactional guarantees. Hence this suggestion. I'm not saying that must be a guarantee, but it would be nice to have if the backend support it.
No, I'm looking for a cache. I know what a cache is. What is a cache if not a "database"? The most popular caches support these operations.
That's also a key point here. You want to be able to reason about expiry etc. as well. In the throttling example you'd like to have a sliding expiration so whenever someone makes a request, it gets incremented and the expiration is reset. When the expiration goes out, the counter is removed (reset).
I doubt anyone using any other cache backend would use throttling middleware that only support Redis. Especially when their existing cache already supports what they need (and could be used instead). Sure, I could roll my own abstraction, but that means I'd have to either leave the implementation up to the end user or ship separate ThrottleMiddleware.Redis, ThrottleMiddleware.Memcached and ThrottleMiddleware.InMemory etc. packages. I'd much rather rely on the existing packages in the shared framework if I could. |
Our understanding of caching here has traditionally been that the data in the cache can never be expected to remain there, it could disappear at any time (due to scavenging, expiration, etc.). I could buy that it's up to the consumer to set that policy though.
Yeah, that does seem to be the case. Fair point. Alright, I can see those points. I guess I'm still not totally clear on how scavenging affects this but I can buy that it's a common enough pattern to be warranted. We still have to reconcile the breaking change angle, since adding this API would force any caching provider to support it. Perhaps we can do something hacky with default interface members but it would require making a lot of assumptions. It's much too late to do this in 3.0 but I'll reopen and backlog this. |
I'm totally fine with introducing a new interface and do a cast check on the injected |
when is this feature getting rolled out |
@abhiyx at this point we have no scheduled release for this feature. We're in the midst of planning for 5.0, and this will be considered there (it will have to be prioritized against other work we have to plan for 5.0 though, so there are no guarantees :)). |
there are any news for this feature ? |
Yeah, I'd still like to get this feature in. What would be the best way to attack this? Submit a PR for an additional interface with the new members? Does it have to go through API review? |
Everything has to go through API review and it's a breaking change and we haven't even agreed that this makes sense on anything besides a redis implementation. |
Adding a separate interface that implementations can opt into is a breaking change?
Most other platforms seems to be able to handle this just fine, whether the backing store is in-memory, Redis, Memcached or SQL-based 🤷♂️ What can we do to further this proposal? |
Check out the API proposal review process here: https://github.com/dotnet/runtime/blob/master/docs/project/api-review-process.md. Specifically this part:
The current proposal on top of this issue would be a breaking change, which we've decided we can't take. To make progress, can you edit the top proposal to match the template with the newly proposed APIs? |
@khellang Any work-around for above-mentioned INCR issue? |
Not really. I ended up just using the Redis API directly and not shipping a library to NuGet as it wouldn't be as useful without proper abstractions. |
I ended up having to switch my abstractions over to the replacements offered by Foundatio just to get increment/decrement. I'd prefer to use those offered by the framework rather than leek Foundatio into all my projects (though I admit there's definite bonus points for all the other stuff their abstractions offer.). |
Hi. Are there any updates on this? We would also love to see this being implemented! |
It would be really nice to have for scenarios like rate limiting.
I don't know about SQL Server support for this, but I guess this would map to Redis'
INCR
andDECR
operations.If the key does not exist, it would be set to 0 before performing the operation. The methods would return the value of key after increment/decrement.
I propose the following new members:
@Eilon @Tratcher @davidfowl Is this something you'd consider for 3.0?
The text was updated successfully, but these errors were encountered: