after about the 20th client of mine did this during training, I decided to file and patch this problem.
The problem:
On a fresh Drupal 7 installation with standard Drupal modules enabled, it is possible to inadvertently disable modules simply by clicking "Save Configuration" twice in succession before the page has had time to reload. I run into this a lot with clients who dont know any better, and don't see the 'loading...' that is being displayed in the overlay. They tend to think nothing happened and click submit again.
The classic symptom is the user asking "where did the toolbar go?" After digging into it, it's almost always that the toolbar, shortcuts and sometimes the overlay modules have been disabled, even though the user never unchecked them. Sometimes even more modules have been disabled - it really depends on how long the user waits between clicks.
This seems to be most common on WAMP or possibly WIMP installs, but also happens on MAMP and other configurations. Generally speaking, as long as the modules page takes a reasonably long amount of time to process and load, this problem becomes more noticeable.
The solution:
Rather than tracking down the race condition that is taking place in the system module build process, it seems that it might make the most sense to implement a lock during the module save process to prevent either users hitting save twice, or two users hitting save at the same time. This seems to do the trick in preventing this problem from reoccurring.
see attached patch for lock implementation.
Hope this helps someone!
-Chris
| Comment | File | Size | Author |
|---|---|---|---|
| module_save_doesnt_lock.patch | 1018 bytes | netw3rker |
Comments
Comment #1
netw3rker commentedComment #2
wim leersCan't we avoid any server-side complexity by simply ensuring that the submit button on the modules page can't be triggered twice? :)
Comment #3
moshe weitzman commentedThere is already a lock on modules page submit, but it is specific to menu rebuild. I guess we could do a lock around the whole form submit
Comment #4
damiankloip commentedI think the lock plan is the only real way to go here. JS is out I would say. I agree with #3.
The initial patch has the lock in system_modules_confirm_form, which wont always be called? Either way, I think this also has to move into 8.x first.
Comment #5
moshe weitzman commentedI think we should understand the problem a bit more. Exactly why would toolbar become disabled if it was never passed to module_disable().
Comment #6
netw3rker commentedYeah i feel JS is out, it really only stops a user with JS enabled from clicking 2x, but not someone clicking refresh, or two people submitting at the same time.
the module save page doesn't have the mentioned locking system on it, moshe is thinking of the menu_rebuild system that has a lock/wait on it to make it single threaded.
per #5, its not just those modules, one users hit it late enough in the game that the views_ui module got disabled! I'm not 100% sure this race condition is something that can fully understood, but my guess (and this is just a guess) is that the system table gets wiped out initially and then begins being populated with enabled modules. when the 2nd process does its form_submit, the values from the db are loaded as available options for the checkboxes, but is missing all of the deleted modules. that submit then wipes the table and populates with just the modules it knows about, leaving a ton of previously enabled modules disabled.
I'll do more digging if it is so demanded, but i think that's probably really close to the crux of the problem. adding a lock/wait system definitely solves this too.
Comment #7
Bojhan commentedWe did think about this already in http://drupal.org/node/483876, I think there we sided against it because of the side-behaviours. Good to get this checked by a11y peeps
Comment #8
mgifford@Bojhan, I just looked at the patch. I don't see any UI changes that would affect accessibility. Didn't install it, but guess I need some clarification. I didn't look at #483876: Disable install button once clicked.
Comment #9
damiankloip commentedI think the outcome so far was that this wouldn't affect the front end. i.e. the button being disabled is not an option.
Comment #10
pwolanin commentedYou need to acquire the lock before proceeding even after the wait it up.
Comment #11
pwolanin commentedI'm adding this kind of code right now to a contrib module:
This kind of helper should maybe be in core even.
Comment #11.0
pwolanin commentedfixed some grammer issues
Comment #20
catchIt's no longer possible to disable modules on this page - since modules can't be disabled. Uninstall happens on a different route. Moving back to 7.x