Skip to content

Different cache key by role#8510

Merged
MatteoPiovanelli merged 9 commits into
OrchardCMS:devfrom
LaserSrl:8509_different_cache_key_by_role
Oct 29, 2021
Merged

Different cache key by role#8510
MatteoPiovanelli merged 9 commits into
OrchardCMS:devfrom
LaserSrl:8509_different_cache_key_by_role

Conversation

@ElenaRepository

Copy link
Copy Markdown
Contributor

added role in the cache key as proposed #8509

@MatteoPiovanelli

Copy link
Copy Markdown
Contributor

@sebastienros We put the feature in the OutputCache Module. In principle, it could go in the Orchard.Roles module (changing only dependencies). Let us know which one you prefer.


namespace Orchard.OutputCache.Handlers {
[OrchardFeature("Orchard.OutputCache.CacheByRole")]
public class CacheByRoleHandler : IRoleEventHandler {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest instead to create a hash based on the permissions of the role, and cache this hash. Then the ICachingEventHandler can just use this value in the key. If the permissions change, the key change, and the old cache becomes obsolete after some time. That's how we do these things in OC.

@MatteoPiovanelli MatteoPiovanelli Sep 24, 2021

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that alternative, because it would prevent the need to evict explicitly. I have a few considerations:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sebastienros could please point out the bit in OC where you are doing what you describe. At a cursory search I did not find it, and I don't know that software well enough to reliably find it by myself.
The file I found that looks more relevant to this is https://github.com/OrchardCMS/OrchardCore/blob/339d74b251b53393dd510f8ad3027aa17d78500d/src/OrchardCore/OrchardCore.Infrastructure/Cache/CacheContextProviders/RolesCacheContextProvider.cs

I was looking for an ICacheContextProvider that that dealt with Permissions and I don't see it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are not doing it for roles, it's just the technique of using hashes as part of the key so that it doesn't need to be evicted. Using a sliding expiration (or at least some absolute one) is necessary so the values don't stay cached forever.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code in this is only contributing to the cachekey. Expiration of the cache entries is controlled elsewhere, configurable through the settings of the OutputCache already.

Comment thread src/Orchard.Web/Modules/Orchard.OutputCache/Filters/CacheByRoleFilter.cs Outdated
@ElenaRepository

Copy link
Copy Markdown
Contributor Author

Cache evict removed for the following reasons:

  • added roles and permissions in the cache key (hashed)
  • added anonymous users management for cache
  • added, for authenticated users, specific key building if user is "Site Owner" (because it has no specific permissions, but roles only)
    We tried different implementations and picked the best one performance-wise.

@MatteoPiovanelli

Copy link
Copy Markdown
Contributor

I'll summarize the open questions regarding this PR here, for my clarity.

The added code is its own feature in the Orchard.OutputCache Module.
Wherever this feature is, it needs dependencies on the following dlls:

  • Orchard.OutputCache, because it implements an interface defined there.
  • Orchard.Roles, because it queries on records defined there to find roles and permissions.
    In module.txt it has dependencies on these features:
  • Orchard.OutputCache, because that's where the implemented filter would be used. This isn't strictly necessary: removing it would mean the filter is useless/never invoked.
  • Orchard.Roles, because we need the records from its migrations to exist.
    Since Orchard.Roles is a Core feature, we decided to have the new Orchard.OutputCache.CacheByRole feature in the Orchard.OutputCache module, to avoid adding a dependency to the Orchard.OutputCache project in the Orchard.Roles project. As a conseguence, the Orchard.OutputCache project now depends on the Orchard.Roles project.
    Is this ok @sebastienros ?

The added code does not affect the expiration of whatever values in output cache it is involved with. It contributes to the cachekey, but those cached pages will expire following their own rules, configured elsewhere. That logic is already in place in the Orchard.OutputCache feature.

I am not 100% sure on using GetHashCode() to hash the strings used as keys. It's fast, so that's a big plus. And we aren't persisting it anywhere, so that's fine too. On application restart the OutputCache is going to be empty, so even if the result changes it's won't be a problem. I am just slightly concerned about the possibility of collisions (https://docs.microsoft.com/en-us/archive/blogs/ericlippert/socks-birthdays-and-hash-collisions). Do you have a better recommendation?

@MatteoPiovanelli

Copy link
Copy Markdown
Contributor

@sebastienros What do you think about this PR?

@MatteoPiovanelli
MatteoPiovanelli merged commit 5e5bf19 into OrchardCMS:dev Oct 29, 2021
@MatteoPiovanelli
MatteoPiovanelli deleted the 8509_different_cache_key_by_role branch December 10, 2021 08:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants