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

Badge cron code is very inefficient and holds up cron

    XMLWordPrintable

    Details

    • Testing Instructions:
      Hide

      I am not sure what kind of testing instructions to put here. It is a performance issue, so you'd need:

      • a couple of large courses
      • some site level and course level badges
      • make sure that only a small part of students can earn some of the badges
      • run cron

      Without the patch, cron would check each user in each badge and badge criteria whether it was completed. With the patch, some users should be filtered out at the beginning. Have no idea how to test that other than compare running time...

      Show
      I am not sure what kind of testing instructions to put here. It is a performance issue, so you'd need: a couple of large courses some site level and course level badges make sure that only a small part of students can earn some of the badges run cron Without the patch, cron would check each user in each badge and badge criteria whether it was completed. With the patch, some users should be filtered out at the beginning. Have no idea how to test that other than compare running time...
    • Workaround:
      Hide

      Turn off badges in Advanced Settings.

      Show
      Turn off badges in Advanced Settings.
    • Affected Branches:
      MOODLE_26_STABLE
    • Fixed Branches:
      MOODLE_27_STABLE
    • Pull from Repository:
    • Pull Master Branch:
      MDL-42965_master

      Description

      I've seen that if you have a manually awarded badge on a course with lots of users (think really really big), it takes a VERY long time to run the cron.

      Looking into it:

      review_all_criteria() gets all enrolled users, and a list of all users who have already earned the badge.
      For all those who haven't earned it, it calls $crit->review(), where $crit is an instance of each of the types of criteria.
      In the case of award_criteria_manual (and possibly others), review() runs a get_record().

      So for a course with 1,000,000 users, that means we perform 1,000,000 get_records. This is obviously slow.

      Even for a small course, this will hammer the DB and kill performance.

      We should be able to pass a cached recordset into criteria.

        Attachments

          Issue Links

            Activity

              People

              • Votes:
                3 Vote for this issue
                Watchers:
                12 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Fix Release Date:
                  12/May/14