Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Session locks

From MoodleDocs

What is a session lock?

When you create a normal moodle page and include config.php then by default a large amount of moodle bootstrapping runs and you will have the $SESSION global setup for you. While the php script is executing it holds a session lock and at the end it writes back to the session an unlocks it. This means that only a single script can run at a time for a given user while holding the session lock. In practice most scripts run quite fast and most of the time is spent sending the result back over the network and so you often don't notice this. But if you have a long running page like a report or backup this starts to be noticed by the end user as a pause while the affected page is blocked waiting for another page to finish execution on the server.

When writing higher performance code it is better to reduce or eliminate the session locks where possible.

Debugging session lock issues

If you have 'pages that are slow' and you profile them and see that you are waiting on a lock to free up then this is potentially an easy thing to fix to improve your overall performance.

$CFG->debugsessionlock = 5; // Time in seconds

When a session is locked for more N seconds a debugging call will be made with details of what the other page was which is holding onto the lock. A good strategy is to set this to a value like 30 seconds and then gradually reduce this down to a very small number of seconds as you identify and fix various issues. As a rule of thumb in an ideal world no page should ever lock the session for more than a second.

Session unlocking

By default core assumes that you might need to mutate the $SESSION object so it will hold a lock on the session until the page finished and a shutdown handler will release the session lock.

If you are working on any page which is potentially long running, then you should cleanly separate logic which runs early which could mutate the session from the long running processing code and unlock the session.

\core\session\manager::write_close();

Read only session in pages

For this to work, READONLY sessions must be enabled as well needing your code to support it.

If you know ahead of time that you will never mutate the session, but you still need to be able to read it, then you can declare your page to be read only. This will mean your page will never block the session in another http request.

define('READ_ONLY_SESSION', true);

Read only sessions in web services

The same is possible in web services. When you declare your web service you can specify it will not need a session lock:

    'core_message_get_unread_conversations_count' => array(
        'classname' => 'core_message_external',
        'methodname' => 'get_unread_conversations_count',
        'classpath' => 'message/externallib.php',
        'description' => 'Retrieve the count of unread conversations for a given user',
        'type' => 'read',
        'ajax' => true,
        'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
        'readonlysession' => true, // We don't modify the session.
    ), 

No session at all

If your script doesn't actually need $SESSION in the first place then save even more processing and locks by declaring:

define('NO_MOODLE_COOKIES', true);

No config is needed

Going to the absolute extreme, if you do not even need the full moodle bootstrap to run then you can skip it via:

define('ABORT_AFTER_CONFIG', true);