Fixing a quiz regrade timeout

Fixing a quiz regrade timeout

by Pedro Martins De Torre -
Number of replies: 3

I am using Moodle 2.1.10 on a Windows Server 2003 server with IIS and a SQL Server 2008 R2 database.

$CFG->dbtype is 'sqlsrv';

Please forgive me, but that old hardware won't run the latest version of Moodle...

Anyway, a student reported that she had completed and passed a quiz, but did not get the expected credit in the gradebook for that course. I can see that the quiz attempt was successfully submitted and graded, but for some reason no grade was written to the gradebook. To fix that I normally regrade the quiz attempt and that solves the problem.

But in this case the quiz attempt regrade abended with a timeout error:

PHP Fatal error: Maximum execution time of 30 seconds exceeded in \lib\dml\sqlsrv_native_moodle_database.php on line 362

The max_execution_time in my php.ini file is set to 1800, so that's not the problem.

So I fired up my PHP editor and had a look at the private function do_query(...) in the \lib\dml\sqlsrv_native_moodle_database.php page. I added a QueryTimeout parameter to sqlsrv_query() like this:

    $sql = $this->emulate_bound_params($sql, $params);
$this->query_start($sql, $params, $sql_query_type);
if (!$scrollable) { // Only supporting next row
$result = sqlsrv_query($this->sqlsrv, $sql);
} else { // Supporting absolute/relative rows
-- $result = sqlsrv_query($this->sqlsrv, $sql, array(), array('Scrollable' => SQLSRV_CURSOR_STATIC));
++ $result = sqlsrv_query($this->sqlsrv, $sql, array(), array('Scrollable' => SQLSRV_CURSOR_STATIC, 'QueryTimeout' => 900));
}

That doesn't seem to have broken anything, but is there any reason for me not to do this? Will it cause any regressions elsewhere in Moodle? (I'll probably revert the change after I've managed to regrade the bad quiz attempt on production.)

This quiz regrade timeout was never a problem in Moodle 2.0.4+ which we were running up until a few weeks ago.
Average of ratings: -
In reply to Pedro Martins De Torre

Re: Fixing a quiz regrade timeout

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

The problem is not really in do_query. That is just where execution happens to be when the time limit expires.

The problem is probably in the quiz code, in the loop where it goes through all attempts and regrades them. That is probably calling set_time_limit(300) every time through the look, in an attempt to prevent time-outs. But, since your time limit is already longer than that, it is a stupid thing for the code to do.

In modern Moodle (https://github.com/moodle/moodle/blob/master/mod/quiz/report/overview/report.php#L364) that is not a problem, the API is actually core_php_time_limit::raise(300); which makes sure the time limit only gets longer, but in your version it is probably using the stupid old code. Here is where it was fixed in Moodle core. https://github.com/moodle/moodle/commit/3ef7279f262099559fc207fd306b0068a6af20e0#diff-d94c25bf5e8b3d07cfcee0e38bc8e0e2R343

In reply to Tim Hunt

Re: Fixing a quiz regrade timeout

by Pedro Martins De Torre -

Thanks Tim,

In https://github.com/moodle/moodle/blob/MOODLE_21_STABLE/mod/quiz/report/overview/report.php#L375 I see that the second line of:

protected function regrade_attempt(...)
in Moodle 2.1 does this:
set_time_limit(30);
Is there anything wrong with me just increasing that to something higher, like:

set_time_limit(90);
just to get passed this particular regrade?

In reply to Pedro Martins De Torre

Re: Fixing a quiz regrade timeout

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Just increasing that number should be fine.

Average of ratings: Useful (1)