How does the session locks work in Moodle (part 3)?

The problem with the session locks is that it may often cause the performance issues for the end users. Imagine that a teacher runs some complicated report. The report generation takes more than one minute. After just few seconds, the teacher gets bored and opens the course page in a new tab instead of waiting for the report. Loading the course page takes forever - this is because the web server has locked the session for the report generation. End-user experience is poor - they will complain that course loading page took a long time (and it did - even though the root reason for this was poor performing custom report).

Triggering \core\session\manager::write_close() will help a bit - we release the lock as soon as we can.

But we can go one step further here - mark some scripts (pages) as no needing the session lock at all. That is a new feature in Moodle 3.9 - READ_ONLY_SESSION implemented in MDL-58018. We promise here that the script will not write to the session.

We do it by declaring READ_ONLY_SESSION before including config.php:

define('READ_ONLY_SESSION', true);

echo "Time start: " . date("H:i:s") . "<br />";
echo "Time end: " . date("H:i:s") . "<br />";

The pre-requisites for the read only sessions are:

  • Enable in config.php by setting:
$CFG->enable_read_only_sessions = true;
  • Change sessions handling to DB. At the moment read only sessions are implemented for DB, Redis and memcached. The work on adding the support for file-bases sessions continues in MDL-68522.

After running page1.php and page2.php one by one, I get the results:

Time start: 17:20:53
Time end: 17:20:58
Time start: 17:20:54
Time end: 17:20:59

No lock at all! The second script started running as soon as my request was received.

The new functionality is currently used in 2 places:

  • lib/ajax/getnavbranch.php - no need to wait for the session lock just to get the navigation menu entries.
  • lib/ajax/service.php - the script starts with no session lock and will continue in this mode if the service being called has readonlysession set to true.

So - get the latest Moodle 3.9, enable $CFG->enable_read_only_sessions, use DB or Redis for your sessions and enjoy the benefits of no locking session calls.