I've developed a feature for the 'devel node access by user' block. Instead of displaying the 'by user' table with all the grants worked out, the table is rendered empty. The Ajax then kicks in and populates the table one cell at a time.
The reason I made this is that certain grants were causing errors. If the devel node access 'by user' block was enabled the whole page would crash and I didn't get any useful feedback. Now if a request doesn't respond with valid json, that table cell is marked with an error message and a link equivalent to the failed request. I have attached a screen shot of a partially loaded table (currently still populating the data), with an error'd cell.
The block shows four grant operations for ten users, so that's 40 calls to fetch grants. In a typical page load, in Drupal that invokes hook_node_grants(), one grant operation is checked for one user. So there is significance in the added overhead with the block. This patch reduces the load time of the page initially, so it is more representative of a typical load without the block. It extreme cases, such as during module development, it may also avoid memory limit and max execution time problems.
You can turn this behavior back to the traditional method of prepopulating the table at once via a configuration option.
I have attached a patch for Drupal 6, plus a new .js file (sorry it's not included in the patch), and the screenshot.
If you're interested I can try for a full patch through git.
| Comment | File | Size | Author |
|---|---|---|---|
| #27 | dna-by-user-ajax-10756440-27.patch | 8.54 KB | danielb |
| #25 | dna-by-user-ajax-10756440-25.patch | 8.88 KB | danielb |
| #23 | dna-by-user-ajax-1075644-23.patch | 8.53 KB | danielb |
| #22 | dna-by-user-ajax-1075644-21.patch | 6.45 KB | danielb |
| #21 | dna-by-user-ajax-1075644-21.patch | 6.45 KB | danielb |
Comments
Comment #1
danielb commentedthis patch has the correct access setting on the callback
(I did change the name of this file after I uploaded, but it didn't seem to take)
Comment #2
salvisThis is interesting in several ways:
1. Where do those errors come from? I've never seen them. We need to fix them! Please open a new issue for them.
2. It's a very interesting concept. This block does cause considerable overhead, which is why it's turned off by default. I'm sure that filling it asynchronously gives you a faster page load, but you're turning 40 (or rather 80) grant evaluations into 40 Drupal bootstraps (plus 2 grant evaluations each). Do you have a feeling for what that does to the server load? Especially on a development machine running under a debugger? I turned the block off by default for performance concerns, but I never actually found a noticeable difference.
3. I think this should be turned off by default for the same reasons.
4. Patches always need to go against the latest branch (D7 at present) first. Nevertheless, we can investigate the merits of this idea under D6 now, but I won't commit it to D6 before D7.
I need some time to get up to speed with Git (just got a book from Amazon) before I look at this, and I'd like to get some third-party opinions on this.
Comments please...
Comment #3
danielb commentedThe problem is caused by the node access module that is being developed. This patch enabled me to pinpoint which cases (which users, and which grant operations) are causing the problems so I could investigate further.
No, I admit I have no appreciation for what this does to server load. I figure if you're developing a site and using Devel node access then you're in an environment where you might not particularly care about this because you have no real users and visitors. It still only does one request at a time, firing them off as the previous response comes in, or if there is no valid response in 3 seconds (that's an arbitrary time - jquery versions before 1.5 unfortunately don't have an ajax on-failure handler).
Fair enough, I kind of went back and forth on this one, and left it on because at least then the page loaded properly in the problem scenario, I liked the way it worked and enjoyed watching the grants appear. I also worry people wouldn't be aware of this feature if they were in a situation where they'd need it.
No problem. I developed it in 6 for what I needed and as a proof of concept / proposal at this stage. Happy to work towards a 7.x patch, perhaps after some more discussion.
You know I spent hours yesterday reading about Git, feeling like I couldn't find the information I was looking for, and then realised there is an incredibly handy guide at the 'Git instructions' tab on the project page of the project you want to work with. Coupled with the 'git access' tab when you edit your user profile, you can do routine patches/commits on projects while you're still learning the finer points of git.
Comment #5
salvisGood point — that's very useful!
I'm less concerned about running on a live site (you're not supposed to do that), but about running under a debugger. First, performance-wise, and second, getting additional requests every 3 seconds makes this completely unusable if you set breakpoints and do single stepping.
You are off-loading the Core and DNA evaluation into one and the same request, right?
I see your point, but we must maximize the chances of working out of the box for the broadest range of users — to minimize the support load. That's the overriding criterion. Those who write a node access module should be nimble enough to find the option.
Also, if it were on by default, then we'd need a non-JS fallback.
If it's off by default, we only need a hint that it's not working without JS, but we do need that. Minimize the support load!!!
Please do mention the consequence of having JS disabled in the description. The word "JavaScript" must appear, some people will not know what "Ajax" means. Minimize the support load!!!
I wonder whether the checkbox should be where you put it, or in the block configuration (like the 'Switch User' settings)...
I finished my first Git book today, and the second one is already waiting. Those instructions are very very basic. For starters they break the promise of not exposing your email address to webcrawlers.
If there's more than one committer to any of the modules that you maintain, then you'll want to read http://www.randyfay.com/node/91...
Comment #6
danielb commentedI suppose that would be the case. You would be better off with the original block, and probably wouldn't benefit as much from this if you've got tools that can step through the code.
I believe so, the callback calls _devel_node_access_explain_access() which does both?
I'll look into the policies you've mentioned.
Comment #7
salvisYes, _devel_node_access_explain_access() does both (see $second_opinion).
Comment #8
danielb commentedI think you should make the call on this one. It doesn't bother me either way, but I think we have a few options:
- On the devel settings page (perhaps 'devel node access' should have it's own fieldset so we don't have to prefix each DNA config with 'Devel Node Access')
- On the block configuration page. Makes logical sense, but people may not think to look there, I even managed to miss the 'switch user' settings the first time I went looking for them after you mentioned it. The 'debug mode' setting also seems to apply specifically to the blocks (?), but that is on the config page.
- On the block itself as a link below the block content, which would switch the setting much like switching between users in the 'switch users' block. This seems the most accessible, but the least 'config'-like option and requires more work/code to implement.
- On the block configuration page, but with a link under the block similar to the 'debug mode' link.
Just some thoughts to consider, I can do it anywhere really.
I could also use some feedback on the text in the configuration setting:
I still want to say 'Ajax' to paint a clear/correct picture for those users that do understand what it means, but as well mention JavaScript as you said. The #title is also a bit awkward.
This text might have to change to suit the context of where the setting ultimately appears.
Comment #9
salvisYes, as soon as we get more than one option, a dedicated (expanded) fieldset will be nice. We'll have to check how it looks if Devel is disabled, though. It makes sense to not spread out the DNA configuration over several pages. I think admin/settings/devel (D6) is best.
A dynamic switch inside the block would be cute, but it seems a bit of overkill here, and there'd have to be too much explanatory text.
How about
[ ] Asynchronously populate the Access permissions by user block
Use Ajax to populate the second DNA block. This loads the initial page faster and uses dynamic calls to build the data in the table, one request at a time. It's especially useful during development, if some of the calls are failing.
JavaScript must be enabled in your browser.
Comment #10
danielb commentedHere is a Drupal 7 git patch for consideration.
Comment #11
salvisA small nit: variable_get() needs to get FALSE as default.
A bigger one: It's not working at all. All cells show "Error: could not explain access," even though they are just fine when filled synchronously.
I know little about AJAX, so I can't really help a lot...
Comment #12
danielb commentedwoops, I only changed the default in the config, not where it's used.
You have to rebuild your menu cache to enable the callback (which would normally happen when the module is installed)Hmm actually that doesn't apply to Drupal 7. Will investigate.Comment #13
danielb commentedsorry about the massive delay on this issue, my ISP isn't providing a working internet connection at home, meaning I pretty much just play solitaire now :(
Comment #14
danielb commentedI've recreated the patch against a fresh git clone of 7.x-1.x, including the variable defaulting to FALSE in both places.
I haven't had any problems like you did with it not working at all, so I don't know what happened there - there is in fact a change in hook_menu, so the menu would need to be rebuilt to be sure.
Please review.
Comment #15
danielb commentedComment #16
danielb commentedI've forgotten how to include the .js file in the patch :(
Comment #17
danielb commentedOK This one includes the .js file.
Comment #18
danielb commentedJust noticed a couple typos
Comment #19
salvisI still get 'Error: could not explain access' in every cell, user 1, after flushing the caches. I tried upping the timeout to 10000, but this hasn't changed anything except for making it slower.
Comment #20
danielb commentedAh oops, looks like I put the menu item inside an existing if statement
<?php if (!module_exists('devel')) { ?>I'll get this fixed up soon.
Comment #21
danielb commentedHere it is again with the menu in the right spot.
Comment #22
danielb commentedHere it is again with the menu in the right spot.
Comment #23
danielb commentedI just realised the newest patch is missing the javascript part :( This is driving me crazy :/
I'm so sorry about this.
Comment #25
danielb commentedRawr, I have rerolled a new patch and retested it. There is a weird thing in the latest dev where the half the dna module file appears commented out, so I've had to change that...
Comment #26
salvisNo, the comment wasn't the issue, it was the format of the patch. Please undo the removal of the slash.
The comment ends there either way. If your editor shows it differently, then that's a bug in your editor.
Comment #27
danielb commentedComment #28
salvisCommitted to D8 and D7. Thanks!