Infinite loop in auth_db_sync_users.php

Infinite loop in auth_db_sync_users.php

by Florent Lartet -
Number of replies: 3
Hi,
I'll try to be clear. I'm on 1.7.1+
When I run auth_db_sync_users.php, I have an inifinite loop on guest users synchronization.
First, Moodle assigns the user correctly
=> Assigned role guest to user 22310 in course 2141 (SOPC41)
that's perfect.

But, when it finishes to do great things, it loops like that line on all guests users.
=> Unassigned role 6 from user 22310 in context 2206

Of course, the context in mdl_context (which I don't know perfectly the meaning)
references the course 2141.
Is there anyone who experimented this problem ?

Thanks,
Florent.
UTM
Toulouse, France.
Average of ratings: -
In reply to Florent Lartet

Re: Infinite loop in auth_db_sync_users.php

by Iñaki Arenaza -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

I'm not sure this is the same issue you are describing, but this comment in .../moodle/enrol/database/enrol.php is somewhat disturbing:

//
// prune enrolments to courses that are no longer in ext auth
//
// TODO: This doesn't work perfectly.  If we are operating without
// roles in the external DB, then this doesn't handle changes of role
// within a course (because the user is still enrolled in the course,
// so NOT IN misses the course).
//
// When the user logs in though, their role list will be updated
// correctly.
//

And this comment is right above the code that unassigns roles.

Saludos. Iñaki.

In reply to Iñaki Arenaza

Re: Infinite loop in auth_db_sync_users.php

by Clinton Graham -
With a sufficiently large user set, I can see how a seemingly "infinite" loop could appear in enrol/database/enrol.php's sync_enrolments(). I've been fighting with this script for the past few days and am now convinced that the SQL just below the section you mention, Iñaki, inappropriately uses a LEFT OUTER JOIN of role_assignments on a join of context and course. This returns a repeated resultset of all 'database' enrolled users, and procedes to unenroll them (over and over)!

I believe enrol/database/enrol.php line 351 (version 1.32) should read:
 JOIN ({$CFG->prefix}context cn
I think the original intent of the outer join was perhaps to look for role_assignments orphans as well as the stated "enrollments for courses no longer in the external database". It just doesn't work that way, though.
In reply to Clinton Graham

Re: Infinite loop in auth_db_sync_users.php

by C Lopez -
I have been looking into this, and it is my feeling that the LEFT JOIN command is theoretically correct, but the problem (in my case, anyway) is that versions pf MySQL before 5.0.1 do not support nested joins. Here we have a command of the form

SELECT * FROM RA LEFT JOIN (C, CN)

And this is a form that explicitly not allowed in MySQL prior to 5.0.1. Basically, these versions of MySQL will just ignore the parentheses. That's what's resulting in this crazy behavior.

Since Moodle is supposed to support MySQL 4.1, the query will have to be rewritten. I think a query of the form

SELECT * FROM RA LEFT JOIN CN LEFT JOIN C

That is,

"SELECT ra.roleid, ra.userid, ra.contextid
FROM {$CFG->prefix}role_assignments ra
LEFT JOIN {$CFG->prefix}context cn
ON ra.contextid = cn.id AND cn.contextlevel = ".CONTEXT_COURSE."
LEFT JOIN {$CFG->prefix}course c ON cn.instanceid = c.id
WHERE ra.enrol = 'database'" .....

will do what was intended here, though it may not be formally equivalent.