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

Simplify redis acquire_lock method

    • Icon: Improvement Improvement
    • Resolution: Unresolved
    • Icon: Minor Minor
    • None
    • 4.4
    • Caching
    • MOODLE_404_STABLE
    • 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. 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_ 

      2. Purge the Redis cache by clicking the Purge link in the Redis line of the table under Configured cache instances.
      3. Select a suitable course id from your test install, keeping an eye on the open terminal.
      4. 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. 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_ 

      2. Purge the Redis cache by clicking the Purge link in the Redis line of the table under Configured cache instances.
      3. Select a suitable course id from your test install, keeping an eye on the open terminal.
      4. 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 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 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 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"

      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.

            Daniel Ziegenberg Daniel Ziegenberg
            frederikmillingpytlick Frederik Milling Pytlick
            Votes:
            2 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:

                Estimated:
                Original Estimate - 0 minutes
                0m
                Remaining:
                Remaining Estimate - 0 minutes
                0m
                Logged:
                Time Spent - 10 minutes
                10m

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