Now that #320132: Make path.inc swappable is in, it'd be a good time to look at a Drupal 7 port. I started some (abandoned) work on a port before that patch got in, but during that process had a few thoughts.
1. We need the two cache bins, but these should also make db tables for the memcache-db.inc situation, and because with the optimizations in HEAD, this won't completely kill a site running db caching any more. The bins should also be renamed in line with the new column names / variable naming in D7.
2. There may still be benefit from the $system_paths variable, since $memcached->get() is multiple, and we have a cache_get_multiple() in core - that would mean on many pages 2-4 requests to memcache instead of 30-40.
3. Otherwise falling back to individual lookup should be fine.
If I have time I may make a start on this, but opening anyway.
| Comment | File | Size | Author |
|---|---|---|---|
| #70 | interdiff.txt | 1.28 KB | fabianx |
| #70 | 652892-pathcache_6xto7x-70.patch | 37.14 KB | fabianx |
| #68 | interdiff.patch | 115 bytes | cameron tod |
| #68 | 652892-pathcache_6xto7x-68.patch | 30.41 KB | cameron tod |
| #59 | pathcache-d6tod7-652892-59.patch | 30.41 KB | extremal |
Comments
Comment #1
catchHere's a patch, keeps the existing optimizations in D7 path.inc - the whitelist and system path cache, then adds caching of individual aliases on top of that. This allows usage of cache_get_multiple() for anything in the system paths cache - which with memcached and a warm cache would mean two memcache hits per page for all aliases, and one in drupal_get_normal_path().
Confirmed that I don't get any database queries for either drupal_get_path_alias() or drupal_lookup_path() with the patch applied.
I didn't implement any expiry at all, only clearing the cache for specific paths on path CUD operations - this is on the assumption that the module would only be used with memcache or a capped mongodb collection. However it might be necessary to add something in there in case people try to use it with something else.
Comment #2
catchFixing a typo.
Comment #4
catchProperly populating the 'no_aliases' array. Also introduced a small hack which allows you to pre-fill the system_paths cache with any arbitrary array of paths (via drupal_static) - this way you can efficiently call url() on large numbers of system paths from cron or other places which won't have a warm cache.
Comment #5
nnewton commentedA big +1 here, for D7 and its pluggable field storage this patch actually helps a lot. In an odd twist of events when you take a bunch of the "large" queries off MySQL, the small ones start to pile up. (who could have guessed...) The url_aliases queries are the top queries on stock D7 + MongoDB in my early testing. This patch to path cache evicts them from the lists and got me 50 more requests per second.
catch++
Comment #8
catchSeveral functions moved from path.inc to bootstrap.inc, updated the patch.
Comment #12
catchComment #13
catchNow caches drupal_get_normal_path() calls when the path isn't an alias.
Comment #14
catchCaching FALSE instead of $source leads to 404s, fix via Jeremy Andrews.
Comment #15
alan evans commentedThe cache is happy to get and set cached paths in a variety of lanuguages and frequently will end up with language_default. However, pathcache_clear_cache only clears the original path language plus LANGUAGE_NONE, resulting in caches not being cleared for, say, language_default(), if language_default() is not the same as the language of the saved path alias, which could be eg. LANGUAGE_NONE.
The only change in this patch from the previous is to clear the cache for the requested path in all configured languages.
Comment #16
pillarsdotnet commentedReworked patch in #15 to match today's Drupal 7.x HEAD
Haven't tested it yet, though...
Comment #17
pillarsdotnet commentedRe-rolled against branch 6.x-1.x of git.drupalcode.org/project/pathcache.git
Comment #18
pillarsdotnet commentedRe-rolled after the Great Git Migration.
Comment #19
pillarsdotnet commentedOkay, I finally re-read the note at the top about path.inc being swappable.
I still think that the module should maintain a patch instead of a copy of path.inc, though.
Re-rolled accordingly, and added install hooks to set the path_inc variable.
Comment #20
ogi commentedsubscribe
Comment #21
basicmagic.net commentedsubscribe
Comment #22
omercioglu commentedsubscribe
Comment #23
rickvug commentedsubscribe
Comment #24
pillarsdotnet commentedIt might also be nice to submit a patch to include it into d8 core.
Comment #25
catchI wouldn't want this in core, it only makes sense if you have memcache installed and would be harmful with the database backend.
Drupal 7 core has the path alias whitelist and per page system-path cache, that is already a big improvement over Drupal 6, it's going to be hard to optimize further without an alternate cache backend in core.
Comment #26
pillarsdotnet commentedEven if it were an optional module that is turned off by default?
How about a d8 patch that only adds the necessary hooks to path.inc that would enable a d8-version of pathcache to run, if it were enabled?
Comment #27
catchIf I we get CacheArrayObject in from the theme registry issue, we could possibly use that for D8 path caching - not sure yet.
If that happens, it'd then be possible to make the PathCache class or whatever pluggable, and that'd allow the module to be implemented from contrib, just extending a class and with a settings.php entry (or whatever D8 has). It'd definitely be good to make this sort of thing easier to do from contrib either way.
Comment #28
pillarsdotnet commentedAre you referring to this issue?
#1011614: Theme registry can grow too large for MySQL max_allowed_packet and memcache default slab size
Comment #29
catchThat's the one :)
Comment #30
marcingy commentedDealing with an issue today and this may indeed also be a core issue.
If I call:
Then the second call returns nothing this is because I have a path_alias_whitelist defined in my settings.php. Calling wipe results in this not getting repopulated. Amending
to
Results in the $cache array being correctly initialised.
Comment #31
dixon_subscribing
Comment #32
mstrelan commentedsubscribe
Comment #33
bryancasler commentedsub
Comment #34
Fidelix commentedSubscribing...
Comment #35
matiki commentedsubscribing
Comment #36
sbuts commentedSubscribing...
Comment #37
basicmagic.net commentedsubscribe
Comment #38
Fidelix commentedbasicmagic.net, STOP subscribing. Start following.
http://drupal.org/node/1306444
Comment #39
berdirLooking at the path.inc differences between the one from the patch and includes/path.inc, I noticed the following:
The comment makes sense, but the anon check seems to be implemented the wrong way round?
Comment #40
alan evans commented@Berdir - agreed, the comment and the code are opposed.
I'm sure I hit this problem on a site (a little hard to remember now though ...) and ended up logging all the path cache entries and realising that what's described in the comment are not all good assumptions, it's generally necessary to analyse what sort of paths are being hit on your site, what paths you have in the whitelist and what additional paths have been created by enabled modules. In short: the behaviour of this chunk won't actually suit everyone's use case.
Anyway ... back to your point - yes, it's the wrong way round.
Comment #41
makara commentedRe-rolled.
README.txtandpath.inc.patchare not included. We can update them after we finish the patch.Comment #42
rickvug commentedThis afternoon I tested the Patch in #41. I'm saving at least 20 queries a page according to Devel. I have not noticed any problems at all. I'm not familiar with path cache's implementation and have not reviewed the code, but simply based on usage experience this would appear RTBC for a first pass. Updating README.txt can come afterwards.
Comment #43
erikwebb commentedI'm seeing a 50+ query improvement on link-heavy pages. I don't see any problems either myself, but I won't RTBC without production environment testing.
Comment #44
pribeh commentedsubscribing.
Comment #45
erikwebb commentedCan we get a 7.x branch commit to start here? Even if it's only in development snapshots, it will be easier to provide further feedback and testing.
Comment #46
marcingy commentedThe patch as it stands does not take into account #30 which prevents whitelist set via variables being populated correctly.
Comment #47
fangel commentedI believe I found a bug in the handling of looking up a source from the cache, and afterwards looking up the alias for the same source..
The code in question is this excerpt:
Say I have an alias 'node/1234' -> 'my-custom-name'
So first I call
drupal_get_path('source', 'my-custom-name', $language), it fails to find the $source in the $cache['map'], so we enter the if-condition. We then lookup the source in the cache, so$cached->data == 'node/1234'. This means that $source will be set to node/1234, so it will set $cache['map'][$path_language]['node/1234'] = 'node/1234';So the next time you then call
drupal_get_path('alias', 'node/1234', $language), it will return 'node/1234', because it's now present in the $cache['map'].I believe the code should be
This way, it will set $cache['map'][$path_language]['node/1234'] = 'my-custom-name'; which is correct!.
Kind regards
Morten.
Comment #48
scripthead commentedsubscribing
Comment #49
anavarreI know that http://tag1consulting.com/patches/path-cache is in D7 but it's often that I can identify url_alias as one of the most consuming DB offender in a D7 site.
Thus I wonder if there's any movement about this? (here or elsewhere, that is)
Comment #50
catchI'm not working on this any more, nor am I using it or recommending it on any sites. It might still be a good idea, but #1209226: Avoid slow query for path alias whitelists is more important and desperately needs reviews/testing etc.
Comment #51
extremal commentedI am using the patch from #41 and it works great apart from one small thing:
When I update the entity, then the "Generate automatic URL alias" checkbox becomes unchecked and the alias doesn't get updated automatically.
I believe this happens due to the
drupal_get_path_alias($uri['path'], $langcode)function in thepathauto_field_attach_formhook implementation.It returns cached alias rather than newly updated.
So I suggest to implement
hook_entity_update()and update the cache for the alias.Comment #52
dgtlmoon commentedThe step to patch the path.inc seems a bit silly, in Drupal-7 you can set a new file for the path.inc include
Comment #53
dgtlmoon commentedApplied your patch, then tried to apply the path.inc.patch from 7.x-1.x
Comment #54
marcelovaniThe patch on #51 probably should not be doing a query and setting the cache, as this could get into a racing condition with the bit of code that is responsible for setting the cache using that same cid.
It would be better if you just cleared the cache bin for that cid i.e.
Or even
Comment #55
extremal commentedThanks, marcelovani.
Replaced
with
cache_clear_all($path_cid, 'cache_path_alias');Works ok to me!
Comment #56
extremal commented@dgtlmoon, I think the path.inc.patch is only for patching D6 version of path.inc
Comment #57
dgtlmoon commentedSweet, thanks man, have applied the re-rolled patch to 6.x and seems to be functioning, not seeing the usual 400 drupal_lookup_calls in my devel module output, waiting to see if any issues come up
Comment #58
girishmuraly commentedAlong with
we may need to also clear 'cache_path_source'.
Comment #59
extremal commentedThanks girishmuraly !
Re-rollled the patch
Comment #60
girishmuraly commentedPatch in #59 works great for me.
Comment #61
shahinam commentedThis looks very stable, why not create a D7 release?
Comment #62
marcelovaniAgree, it works fine and should be committed
Comment #63
jgsantos commentedI agree. I tested and it worked for me too.
Comment #64
marcingy commentedThe issue is https://drupal.org/comment/4651040#comment-4651040 still exists and is an on going item that needs fixed.
Comment #65
fabianx commentedI disagree with you, marcingy here.
This just means that:
* If you use whitelists in Drupal 7, don't use this module as there is a bug.
**RTBC** again - lets get this in, then deal with the whitelists bug.
Comment #66
fabianx commentedI looked into this:
And the only thing needed is:
as marcingy pointed out and I saw now that it needs to be NULL instead of array ...
The reason is that the check above does more:
Again this is no issue when not using 'path_alias_whitelist' variable.
And the check for re-init does use:
if (!isset())
Can someone re-roll the patch, please so we can get this committed?
Comment #67
seja12 commentedCan anyone provider a full working module for this. I keep getting errors when I try to apply the patches.
Comment #68
cameron tod commentedJust that small change is all that is needed?
Comment #69
fabianx commentedNope, both changes are needed.
Remove the:
- $cache = array();
+ $cache = NULL;
- $cache['whitelist'] = drupal_path_alias_whitelist_rebuild();
whitelist as well.
Comment #70
fabianx commentedHere is the final patch. I also changed the README for D7 that path.inc should be included.
Comment #71
nimek commentedCan you post files as ready drupal 7 module?
Comment #72
tyler-durden commentedI second the request for a full Drupal 7 module, if this seems to be working properly now. 100's of path requests per page load is a little ridiculous, and is the biggest eater of queries on my pages now.
Comment #73
berdirThere shouldn't be hundreds of queries with Drupal 7's default caching implementation. Note that there is a major issue in redirect that is breaking the path cache: #2048137: Canonical redirect breaks path cache
Comment #74
fabianx commentedEven with redirect disabled, I saw enough queries in new relic to justify the existence of this module / patch.
I will track down the maintainer of path_cache again and am willing to co-maintain.
Comment #75
marcingy commented@fabianx if you get co-maintainership and need some assistance I or one of the other devs at examiner.com will also be willing to step up as co-maintainer.
Comment #76
tyler-durden commentedThanks everyone for helping. I was able to reduce my queries by close to 20% on some pages, so this module is a big help.
However I have just found that this D7 patch breaks the "Path Auto" module. All current paths still work, however once the "Path Cache" module is enabled you are no longer able to edit any new paths, and the default paths do not work on new nodes either. Once Path Cache is disabled AND uninstalled, only then does Path Auto work properly again.
There are no error messages on the screen or in the logs to report. I'm not a programmer, so I cannot add anymore than what I just found.
Comment #77
fabianx commentedI am a co-maintainer now and will also onboard marcingy as co-maintainer, too per #75. The 7.x-1.x branch should be opened soon. :)
Comment #78
fabianx commented#76: Did you try if installing pathauto_persist would solve that problem?
Comment #79
fabianx commented#75: Added you as a maintainer now, feel free to add more from examiner. I am a strong believer in teams! :)
Comment #80
marcingy commentedThanks Fabianx I have also added slashrsm(https://www.drupal.org/u/slashrsm).
Comment #81
tyler-durden commentedI originally didn't try Pathauto_persist because it seemed like it was fixing a separate issue. I just tried it and it did not resolve the issue.
Comment #82
marcelovaniHey, great to know we have new maintainers, I have also worked on this patch and it's been a lot of time waiting for this to be committed. I did not have any issue with Path Auto
Comment #83
tyler-durden commentedI don't have access to a shell script/service, so I patched the files "manually". I fear I likely messed something up, so I will be eager to try a proper 7.x-1.x version when it is available and test again.
Comment #85
fabianx commentedAAAAAND ....
Fixed!
Thanks so much everyone.
7.x-1.x branch exists now, will create versions, etc. now.
Lets create issues for any issues.
Comment #86
fabianx commentedI also fixed as a quick follow-up the whitelist change that again sneaked in ...
Comment #87
fabianx commentedComment #89
tyler-durden commentedThanks all! Just to note, it must have been a patch issue for me as this new version is working as expected.