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

Course: Adding graded activity does not show progress bar when slow due to lots of grades

XMLWordPrintable

    • Icon: Improvement Improvement
    • Resolution: Fixed
    • Icon: Minor Minor
    • 4.2
    • 3.11.10, 3.11.11
    • Course, Gradebook
    • MOODLE_311_STABLE
    • MOODLE_402_STABLE
    • MDL-75878-master
    • Hide

      You will need to have access to save and run CLI scripts in your Moodle installation.

      1 In your Moodle, go to Site administration / Development / Make test course and create a medium (M) sized course with your preferred short name and full name.
      2 In the test courses, users do not have grades, so we will create some. Save the file creategrades.php (attached to this issue) into the root directory of your Moodle installation.
      3 Run it with php creategrades.php 1234 where 1234 is the course id of your medium test course. This script will create random grades for all users on all 100 assignments on the course, but you don't need to wait for it to do that (which will take several hours). Just wait until it says Assignment 1: done (which should be less than 5 minutes) then press Ctrl+C to exit the script.

      • For some reason I don't understand, this is actually enough to fill in blank grades for all the assignments, so it has the full performance impact just like running it for all of them.

      4 Back in your medium course, turn editing on and click Add an activity or resource and then choose Quiz.
      5 Type in a name for the quiz, but make no other changes (don't save yet)
      6 Click Save and display

      • EXPECTED: You should be taken to another page with heading Recalculating grades and a progress bar. (Depending on the configuration of your web server, the page might not actually appear before the progress bar finishes.)

      7 Click Continue

      • EXPECTED: You should get to the quiz activity.

      8 Repeat steps 4-7, but this time click Save and return to course. After clicking Continue you should get back to the course as expected.
      9 On the course page, add a new Forum. Type in a name and leave other options default, except under Whole forum grading set the Grade type to Point.
      10 Click Save and display

      • EXPECTED: You should be taken to the 'Recalculating grades' page with a progress bar.

      11 Click Continue

      • EXPECTED: You should get to the forum.

      For the next few tests, we will check that the new script (modregrade.php) is not used in cases where it isn't needed. In each case the process is to check the network panel in browser developer tools to see if there was any request to the modregrade.php script (there should not be). It will help to clear the network panel just before hitting save. The reason for checking in developer tools is that it is possible (but not very likely) that you can get to that script without noticing it visually, because when regrading is not needed, it will immediately redirect.

      12 Turn on browser developer tools and go to the Network panel. (You might also want to click the button to clear any existing data in the panel.)

      13 Edit settings for one of the quiz activities and save changes.

      • EXPECTED: There should be no request to modregrade.php (because the grade item did not need regrading).

      14 Add an activity which does not support grades, such as Page.

      • EXPECTED: There should be no request to modregrade.php (because grades are not supported).

      15 Add an activity which does support grades but where they are not turned on, such as Forum with default settings.

      • EXPECTED: There should be no request to modregrade.php (because grades are not supported).

      16 Using a different test course (make a new one if necessary) which has less than 100 user grades (e.g. none), add a quiz activity.

      • EXPECTED: There should be no request to modregrade.php (because the grade API doesn't think a progress bar is needed).

      The next tests are to check the grade overview report still works. There were no substantive changes to this report, but I made a minor change to address a not-readily-reproducible bug in the existing code, so we should check that it still works.

      17 (If not already done.) Enrol your administrator account into at least 2 courses which have at least one assignment or other gradeable item.
      18 (If not already done.) Give them a different grade in each course, e.g. by grading the assignment.
      19 On one of the courses, go to Grades, then from the top dropdown choose Overview report.
      20 If not already showing, use the Select a user field to select the administrator account.

      • EXPECTED: The report should show the administrator's grade in the 2 (or more) courses they are enrolled in.
      • EXPECTED: The grade shown for each course should match the value shown within the individual course (you can get to that just by clicking the course name from this screen).

      21 Go to Site administration / Server / Web services / Overview.
      22 Ensure that step 1 shows 'Enabled' (if not, click the link to enable) and step 2 shows 'rest' (if not, click the link to configure it).
      23 Follow the link from step 5 to get to the Services screen. Under Custom services, click Add. Type in Toad for the Name field, and toad for the short name field. Turn on the Enabled tickbox. Leave other options default and click Add.
      24 Click Add functions and search for gradereport_overview_get_course_grades, then click Add functions.
      25 Go to Site administation / Server / Web services / Manage tokens and click Create token.
      26 For User, select the administrator account. For Service, select Toad. Leave other options default and press Save changes.
      27 In the list of tokens, you should now be able to find the new token (for administrator on the toad service). It will be a long number, such as 6cf43c4fed8a422751c8c4a3ff51e367.
      28 Construct a URL based on your Moodle root URL and the token above: ROOT/webservice/rest/server.php?wstoken=TOKEN&wsfunction=gradereport_overview_get_course_grades&moodlewsrestformat=json. For example, to do this on my laptop I used this URL: http://localhost/core-moodle-github/webservice/rest/server.php?wstoken=6cf43c4fed8a422751c8c4a3ff51e367&wsfunction=gradereport_overview_get_course_grades&moodlewsrestformat=json
      29 Load this URL and look at the results.

      • EXPECTED: You should see a JSON format results display, showing the same scores that were visible on the report screen. Typically it looks like the below (if your grades are 45 and 21 on the two course):

      	
      grades:	
      0:
      courseid: 9
      grade:    "45.00"
      rawgrade: "45.00000"
      1:
      courseid: 3
      grade:    "21.00"
      rawgrade: "21.00000"
      warnings: []
      

      Show
      You will need to have access to save and run CLI scripts in your Moodle installation. 1 In your Moodle, go to Site administration / Development / Make test course and create a medium ( M ) sized course with your preferred short name and full name. 2 In the test courses, users do not have grades, so we will create some. Save the file creategrades.php (attached to this issue) into the root directory of your Moodle installation. 3 Run it with php creategrades.php 1234 where 1234 is the course id of your medium test course. This script will create random grades for all users on all 100 assignments on the course, but you don't need to wait for it to do that (which will take several hours). Just wait until it says Assignment 1: done (which should be less than 5 minutes) then press Ctrl+C to exit the script. For some reason I don't understand, this is actually enough to fill in blank grades for all the assignments, so it has the full performance impact just like running it for all of them. 4 Back in your medium course, turn editing on and click Add an activity or resource and then choose Quiz . 5 Type in a name for the quiz, but make no other changes (don't save yet) 6 Click Save and display EXPECTED: You should be taken to another page with heading Recalculating grades and a progress bar. (Depending on the configuration of your web server, the page might not actually appear before the progress bar finishes.) 7 Click Continue EXPECTED: You should get to the quiz activity. 8 Repeat steps 4-7, but this time click Save and return to course . After clicking Continue you should get back to the course as expected. 9 On the course page, add a new Forum. Type in a name and leave other options default, except under Whole forum grading set the Grade type to Point . 10 Click Save and display EXPECTED: You should be taken to the 'Recalculating grades' page with a progress bar. 11 Click Continue EXPECTED: You should get to the forum. For the next few tests, we will check that the new script (modregrade.php) is not used in cases where it isn't needed. In each case the process is to check the network panel in browser developer tools to see if there was any request to the modregrade.php script (there should not be). It will help to clear the network panel just before hitting save. The reason for checking in developer tools is that it is possible (but not very likely) that you can get to that script without noticing it visually, because when regrading is not needed, it will immediately redirect. 12 Turn on browser developer tools and go to the Network panel. (You might also want to click the button to clear any existing data in the panel.) 13 Edit settings for one of the quiz activities and save changes. EXPECTED: There should be no request to modregrade.php (because the grade item did not need regrading). 14 Add an activity which does not support grades, such as Page. EXPECTED: There should be no request to modregrade.php (because grades are not supported). 15 Add an activity which does support grades but where they are not turned on, such as Forum with default settings. EXPECTED: There should be no request to modregrade.php (because grades are not supported). 16 Using a different test course (make a new one if necessary) which has less than 100 user grades (e.g. none), add a quiz activity. EXPECTED: There should be no request to modregrade.php (because the grade API doesn't think a progress bar is needed). The next tests are to check the grade overview report still works. There were no substantive changes to this report, but I made a minor change to address a not-readily-reproducible bug in the existing code, so we should check that it still works. 17 (If not already done.) Enrol your administrator account into at least 2 courses which have at least one assignment or other gradeable item. 18 (If not already done.) Give them a different grade in each course, e.g. by grading the assignment. 19 On one of the courses, go to Grades, then from the top dropdown choose Overview report . 20 If not already showing, use the Select a user field to select the administrator account. EXPECTED: The report should show the administrator's grade in the 2 (or more) courses they are enrolled in. EXPECTED: The grade shown for each course should match the value shown within the individual course (you can get to that just by clicking the course name from this screen). 21 Go to Site administration / Server / Web services / Overview . 22 Ensure that step 1 shows 'Enabled' (if not, click the link to enable) and step 2 shows 'rest' (if not, click the link to configure it). 23 Follow the link from step 5 to get to the Services screen. Under Custom services , click Add . Type in Toad for the Name field, and toad for the short name field. Turn on the Enabled tickbox. Leave other options default and click Add . 24 Click Add functions and search for gradereport_overview_get_course_grades, then click Add functions . 25 Go to Site administation / Server / Web services / Manage tokens and click Create token . 26 For User , select the administrator account. For Service , select Toad . Leave other options default and press Save changes . 27 In the list of tokens, you should now be able to find the new token (for administrator on the toad service). It will be a long number, such as 6cf43c4fed8a422751c8c4a3ff51e367. 28 Construct a URL based on your Moodle root URL and the token above: ROOT /webservice/rest/server.php?wstoken= TOKEN &wsfunction=gradereport_overview_get_course_grades&moodlewsrestformat=json. For example, to do this on my laptop I used this URL: http://localhost/core-moodle-github/webservice/rest/server.php?wstoken=6cf43c4fed8a422751c8c4a3ff51e367&wsfunction=gradereport_overview_get_course_grades&moodlewsrestformat=json 29 Load this URL and look at the results. EXPECTED: You should see a JSON format results display, showing the same scores that were visible on the report screen. Typically it looks like the below (if your grades are 45 and 21 on the two course): grades: 0: courseid: 9 grade: "45.00" rawgrade: "45.00000" 1: courseid: 3 grade: "21.00" rawgrade: "21.00000" warnings: []

      When you add an activity that has a grade item (e.g. Quiz) to a course, if there are a large number of existing grades on the course, adding the activity takes a long time because a call to grade_regrade_final_grades makes a large number of database queries.

      On specific courses on two of our live Moodle instances, in infrastructure where database connections have relatively high latency, this behaviour can cause the system to exceed a 1 minute timeout in our infrastructure, meaning that users are unable to add these activities.

      This change makes it so that when you add an activity that has a grade item, if there are a lot of grades, the regrade step is moved to a second web request (immediately after the activity has been added) using existing code to show a progress bar. That way, it still takes a long time, but users see progress and can successfully add the activity without anything timing out.

      An example Moodle perf line from a test setup is below. Note that it makes approximately 10,000 database queries (6.1k read, 3.4k write) just to add a new activity with a grade item.

      [2022-10-03 14:05:53.420296 GMT] [php:notice] [pid 4536:tid 1204] [client 127.0.0.1:53463] PERF: /core-moodle-github/course/modedit.php time: 15.324903s method: POST memory_total: 10364272B (9.9\xc2\xa0MB) memory_growth: 9905072B (9.4\xc2\xa0MB) memory_peak: 12496168B (11.9\xc2\xa0MB) includecount: 362 contextswithfilters: 0 filterscreated: 4 textsfiltered: 0 stringsfiltered: 0 langcountgetstring: 966 db reads/writes: 6062/3436 db queries time: 4.66262s Session (core
      session
      file): 16.1\xc2\xa0KB sessionwait: 0.009 secs

      It might be possible to improve performance of the grade update process (

      Alternative options considered during the development were:

      • Improve performance of the grade update process. In this test case there should have been no impact on the final grades and anyway as there are only 1,000 users I don't see why there were 3.4k database writes), but I didn't spot an easy way to do this safely - or at least, not one that would be an order-of-magnitude boost that we need. Depending on how the course grade is calculated, it's possible that adding a new grade item could indeed require everyone's final grade to be updated.
      • Use an ad-hoc task to do the regrade. I considered this and it still might be a good option, but I was concerned that during the time lag waiting for the adhoc task to run (if the task scheduler is busy), it's possible a student request could trigger the regrade, and I would rather have a long delay when staff add an activity, vs. a long inexplicable delay when a student looks at something.

            quen Sam Marshall
            quen Sam Marshall
            Katie Ransom Katie Ransom
            Ilya Tregubov Ilya Tregubov
            Kim Jared Lucas Kim Jared Lucas
            Votes:
            0 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated:
              Resolved:

                Estimated:
                Original Estimate - Not Specified
                Not Specified
                Remaining:
                Remaining Estimate - 0 minutes
                0m
                Logged:
                Time Spent - 2 hours, 50 minutes
                2h 50m

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