(Tentatively marking this as a bug report, although it's possible that I'm not fully grasping the Authcache + Cache Expiration + Authcache Enum workings, feel free to mark as support request if that is the case).
While trying to set up automatic cache expiration through Authcache Builtin Cache Expiration v2 (and dependencies) on a site that already had Authcache + Authcache Ajax set up and configured, I ran into the following issue:
Since we don't care about varying the cached pages per roles (elements that vary per user/role are retrieved as fragments), we implemented hook_authcache_key_properties()
as follows:
/**
* Implements hook_authcache_key_properties_alter().
*/
function module_authcache_key_properties_alter(&$properties) {
// Do not vary the cache by roles.
// Note that due to the way keys are generated, we still end up with a
// separate cache entry for anonymous vs authenticated users.
unset($properties['roles']);
}
This works fine, and limits the number of cache entries in the cache_page table.
However, now that we are trying to implement cache expiration, we ran into 2 issues:
A) Since we've removed the roles from key generation, Authcache Enumerate should not take these into account when generation all possible keys. However, the current API does not allow me to remove the 'roles' property from the list of properties returned in authcache_enum_authcache_enum_key_properties()
. authcache_enum_key_properties_alter()
only allows me to tinker with the generated keys, and not the properties-array used to calculate possible keys, so a) all keys generated by authcache_enum_user_keys() are incorrect and I need to remove them, b) I need to redo the calculation with the correct input properties.
B) We have about 15 separate base urls, and need a separate cache entry for any given page on each of these urls (since language of the page is derived from the base url. However, the default implementation of
hook_authcache_enum_key_properties()
is as follows:
/**
* Implements hook_authcache_enum_key_properties().
*/
function authcache_enum_authcache_enum_key_properties() {
global $base_root;
$func = variable_get('authcache_enum_role_combine', '_authcache_enum_default_role_combine');
return array(
'base_root' => array(
'name' => t('The root URL of the host, excluding the path'),
'choices' => array($base_root),
),
'roles' => array(
'name' => t('User roles'),
'choices' => call_user_func($func),
),
);
}
It seems that there is no way to alter the 'choices' for base_root
prior to key calculation, so not all possible cache keys are calculated, only those for the active domain.
Other than that, it feels that the current API functions go against the Drupal paradigm of having a hook_properties()
and a hook_properties_alter()
, where the properties_alter
-hook allows you to change the values returned by the properties_hook. In the case of Authcache Enumerate, hook_authcache_enum_key_properties()
returns the properties, while hook_authcache_enum_key_properties_alter()
alters the calculated result, not the properties.
I've altered authcache_enum_user_keys()
so that hook_authcache_enum_key_properties_alter()
allows altering the input properties array, and a new hook hook_authcache_enum_user_keys_alter()
allows altering of the calculated values.
Comment | File | Size | Author |
---|---|---|---|
#17 | 2543352-17-authcache-enum-key-altering.patch | 9.39 KB | mr.baileys |
#17 | 2543353-14-17-inderdiff.txt | 655 bytes | mr.baileys |
#14 | unable_to_alter-2543352-14.patch | 9.39 KB | znerol |
#14 | interdiff.txt | 5.62 KB | znerol |
#12 | 2543352-6-authcache-enum-property-altering.patch | 4.35 KB | znerol |
Comments
Comment #4
znerol CreditAttribution: znerol commentedSeems like the test-bot does not download all dependencies. Perhaps that works better on the
dev
branch.Instead of renaming an existing hook, I'd prefer to introduce a new one. In fact I believe that the alter-hook is correct, since the data structure is very similar to the one from
hook_authcache_key_properties
. In contrast the hook invoked on top of the function is more like an info-hook. Therefore I'd rather rename that. It would even be possible to keep the old around for some time for compatibility reasons. E.g.:Comment #6
mr.baileysMakes sense, updated patch attached:
Note that I'm seeing numerous test failures locally, but I'm getting the same failures without this patch applied, so it might be related to my environment.
Comment #7
znerol CreditAttribution: znerol commentedThanks, looks good. About the second problem (
base_root['choices']
being populated by only the active site), do you think there is a generic solution for that problem? Maybe try to retrieve a list of base URLs from the language module?Comment #8
znerol CreditAttribution: znerol commentedI do not have much experience with multilingual sites. Maybe something like this might work:
Comment #9
znerol CreditAttribution: znerol commentedSeems like the following code fragment works for prefix as well as domain based multilingual sites (tried it in a PHP block):
Comment #10
znerol CreditAttribution: znerol commentedI wonder whether we need to add an option for https-links as well?
Comment #11
znerol CreditAttribution: znerol commented#9 only makes sense for domain based language negotiation. When using a path prefix, then the
$base_root
will stay the same. Also I'm wondering whether it is really desirable to always expire all the languages. If the expiry hook was fired after a node translation was edited, then it is likely that only pages of that language should be expired - at least by default.With #6 it is possible to customize the behavior, so I'm tempted to just commit that and ignore the base root part. Any opinions?
Comment #12
znerol CreditAttribution: znerol commentedUploading #6 again to trigger a new test run after #2546624: Add test coverage for Authcache Enum API.
Comment #13
mr.baileysIn our case we are actually not translating nodes, and each node is usually only viewed in one language. However, since it is technically possible to visit a Dutch node on an English domain, we decided to include the base URL in enum key generation (hence this patch :) ). I assume that you'd also want expiry across languages when certain properties are shared (for example the price on a product).
As per #11, given that every site is unique, I think it's fine to leave customising the behaviour in the hands of implementors. With the patch it should be trivial to add or remove factors for key generation and tailor expiration for any site.
Comment #14
znerol CreditAttribution: znerol commentedAdd tests.
Comment #15
joelpittetWas upgrading something to test this out and I think this may be wrong?
Should this be hook_authcache_enum_key_property_info()?
Comment #16
joelpittetAlso once I fixed that, I got this error after saving.
Edit: this may because I had both hooks implemented...
Comment #17
mr.baileys#15 => good catch, updated.
Comment #18
joelpittetThis is looking pretty good and doesn't hurt having more tests:)
It got some language stuff working with this:
Comment #20
znerol CreditAttribution: znerol commentedThank you, and sorry for the delay.