Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-80815

Simplify redis acquire_lock method

XMLWordPrintable

    • MOODLE_404_STABLE
    • MOODLE_500_STABLE
    • MDL-80815_simplify-redis-acquire_lock-method
    • Hide

      Prerequisite

      • You will need to have access to a Redis server. It can be running on your machine or elsewhere. Windows users can use Memurai if desired.

      Setup using Docker

      1. Install the PHP Redis extension (replace "X" with your server's PHP version, e.g. 8.0)

        sudo apt update && sudo apt install -y phpX-redis

      2. Enable the Redis PHP extension.
      3. Restart your web server.
      4. Confirm the Redis PHP extension is enabled: "php -i | grep redis" - You should see a bunch of lines related to Redis.
      5. Install Redis. e.g. using Docker

        docker run --name redis -p 6379:6379 -d redis

      6. Setup Redis as the session handler, e.g. copy the following to your config.php:

        $CFG->session_handler_class = '\core\session\redis';
        $CFG->session_redis_host = '127.0.0.1';
        $CFG->session_redis_port = 6379;
        

      7. Configure your MUC cache (via Site administration / Plugins / Caching / Configuration / Cache administration) so that it has a Redis cache:
        1. Add a Redis instance by clicking the Add instance link in the Redis line of the table under Installed cache stores.
        2. Set the store name to whatever you like, the server to wherever you have a Redis server installed (E.g. localhost)
        3. Set the Key prefix' to an easily distinguishable value, eg. 4242_.
        4. Save settings
      8. Set the core/coursemodinfo cache to use the Redis cache:
        1. Under Known cache definitions find the line with coursemodinfo and click Edit mappings.
        2. Change the Primary store to your Redis instance (whatever you called it).
        3. Save settings.

      Before applying the patch

      Manual Testing

      1. Checkout to the previous weekly release.
      2. To see if Redis is being used, in a prompt on the server type the following command (replace "4242_" with the Key prefix you set earlier):

        redis-cli monitor | grep 4242_ 

      3. Purge the Redis cache by clicking the Purge link in the Redis line of the table under Configured store instances.
      4. Select a suitable course id from your test install, keeping an eye on the open terminal.
      5. Confirm that you see a SETNX and an EXPIRE command for the created lock, eg.

        1724359413.837901 [0 [::1]:52870] "SETNX" "4242_2-609a980901cad2119e4cc965e0ff2850" "s:32:\"f41b22dea89abd0af0f910da38e2ade2\";"
        1724359413.837980 [0 [::1]:52870] "EXPIRE" "4242_2-609a980901cad2119e4cc965e0ff2850" "600"
        

      After applying the patch

      Manual Testing

      1. Checkout the the latest main branch.
      2. To see if Redis is being used, in a prompt on the server type the following command (replace "4242_" with the Key prefix you set earlier):

        redis-cli monitor | grep 4242_ 

      3. Purge the Redis cache by clicking the Purge link in the Redis line of the table under Configured cache instances.
      4. Select a suitable course id from your test install, keeping an eye on the open terminal.
      5. Confirm that you see only a SET command for the created lock, eg.

        1724359503.664419 [0 [::1]:46242] "SET" "4242_2-609a980901cad2119e4cc965e0ff2850" "s:32:\"f41b22dea89abd0af0f910da38e2ade2\";" "ex" "600" "nx"
        

      Show
      Prerequisite You will need to have access to a Redis server. It can be running on your machine or elsewhere. Windows users can use Memurai if desired. Setup using Docker Install the PHP Redis extension (replace " X " with your server's PHP version, e.g. 8.0) sudo apt update && sudo apt install -y phpX-redis Enable the Redis PHP extension. Restart your web server. Confirm the Redis PHP extension is enabled: " php -i | grep redis " - You should see a bunch of lines related to Redis. Install Redis. e.g. using Docker docker run --name redis -p 6379:6379 -d redis Setup Redis as the session handler, e.g. copy the following to your config.php : $CFG ->session_handler_class = '\core\session\redis' ; $CFG ->session_redis_host = '127.0.0.1' ; $CFG ->session_redis_port = 6379; Configure your MUC cache (via Site administration / Plugins / Caching / Configuration / Cache administration ) so that it has a Redis cache: Add a Redis instance by clicking the Add instance link in the Redis line of the table under Installed cache stores . Set the store name to whatever you like, the server to wherever you have a Redis server installed (E.g. localhost) Set the Key prefix ' to an easily distinguishable value, eg. 4242_ . Save settings Set the core/coursemodinfo cache to use the Redis cache: Under Known cache definitions find the line with coursemodinfo and click Edit mappings . Change the Primary store to your Redis instance (whatever you called it). Save settings. Before applying the patch Manual Testing Checkout to the previous weekly release . To see if Redis is being used, in a prompt on the server type the following command (replace "4242_" with the Key prefix you set earlier): redis-cli monitor | grep 4242_ Purge the Redis cache by clicking the Purge link in the Redis line of the table under Configured store instances . Select a suitable course id from your test install, keeping an eye on the open terminal. Confirm that you see a SETNX and an EXPIRE command for the created lock, eg. 1724359413.837901 [0 [::1]:52870] "SETNX" "4242_2-609a980901cad2119e4cc965e0ff2850" "s:32:\"f41b22dea89abd0af0f910da38e2ade2\";" 1724359413.837980 [0 [::1]:52870] "EXPIRE" "4242_2-609a980901cad2119e4cc965e0ff2850" "600" After applying the patch Manual Testing Checkout the the latest main branch. To see if Redis is being used, in a prompt on the server type the following command (replace "4242_" with the Key prefix you set earlier): redis-cli monitor | grep 4242_ Purge the Redis cache by clicking the Purge link in the Redis line of the table under Configured cache instances . Select a suitable course id from your test install, keeping an eye on the open terminal. Confirm that you see only a SET command for the created lock, eg. 1724359503.664419 [0 [::1]:46242] "SET" "4242_2-609a980901cad2119e4cc965e0ff2850" "s:32:\"f41b22dea89abd0af0f910da38e2ade2\";" "ex" "600" "nx"
    • Hide

      Code verified against automated checks.

      Checked MDL-80815 using repository: https://github.com/ziegenberg/moodle

      More information about this report

      Built on: Fri Mar 21 14:26:30 UTC 2025

      Show
      Code verified against automated checks. Checked MDL-80815 using repository: https://github.com/ziegenberg/moodle main (0 errors / 0 warnings) [branch: MDL-80815_simplify-redis-acquire_lock-method | CI Job ] More information about this report Built on: Fri Mar 21 14:26:30 UTC 2025
    • Show
      Launching automatic jobs for branch MDL-80815 _simplify-redis-acquire_lock-method https://ci.moodle.org/view/Testing/job/DEV.02%20-%20Developer-requested%20PHPUnit/18466/ PHPUnit (sqlsrv) https://ci.moodle.org/view/Testing/job/DEV.01%20-%20Developer-requested%20Behat/63239/ Behat (NonJS - boost and classic) https://ci.moodle.org/view/Testing/job/DEV.01%20-%20Developer-requested%20Behat/63240/ Behat (Firefox - boost) https://ci.moodle.org/view/Testing/job/DEV.01%20-%20Developer-requested%20Behat/63241/ Behat (Firefox - classic) https://ci.moodle.org/view/Testing/job/DEV.01%20-%20Developer-requested%20Behat/63242/ App tests (stable app version) --> unrelated failure, please ignore. Built on: Fri Mar 7 06:26:28 UTC 2025

      The aquire_lock method currently both sets and updates key's in redis, but could be kept to only setting them. This makes more sense and is simpler.

       

      Currently it does the following:

      1. Set's the new lock if it doesn't exist in one go
      2. Updates the key in redis with an expiry

      This seems risky, what if it somehow crashes before an expiry is set? It will be locked forever!

       

      Shouldn't it do the following?:

      1. Check if lock exists
      2. Set the new lock with expiry in one go

      This removes the previous mentioned risk and seems more simple.

        1. MDL-80815.png
          485 kB
          Ron Carl Alfon Yu
        2. modinfo_lock_test.php
          3 kB
          Frederik Milling Pytlick

            Daniel Ziegenberg Daniel Ziegenberg
            frederikmillingpytlick Frederik Milling Pytlick
            Luca Bösch Luca Bösch
            Huong Nguyen Huong Nguyen
            Ron Carl Alfon Yu Ron Carl Alfon Yu
            Votes:
            3 Vote for this issue
            Watchers:
            12 Start watching this issue

              Created:
              Updated:
              Resolved:

                Estimated:
                Original Estimate - 0 minutes
                0m
                Remaining:
                Remaining Estimate - 0 minutes
                0m
                Logged:
                Time Spent - 4 hours, 54 minutes
                4h 54m

                  Error rendering 'clockify-timesheets-time-tracking-reports:timer-sidebar'. Please contact your Jira administrators.