Currently, the state diagram for quiz attempts looks like this:
This imposes two limitations which cause performance bottlenecks:
- Because a newly created quiz attempt goes straight into the 'in progress' state, we are required to go straight from the quiz attempt not existing, to the state where the quiz attempt is fully initialised. Therefore, all the work to create the attempt, randomly select question from the bank, and initialise them all, must be done synchronously when the students clicks 'Start attempt'.
- Similarly, becuase we have to do the transition In progress -> Finished, in a single step, we must do all the work of finishing all question when handling 'Submit all and finish'.
The plan is two introduce two new states:
- Created: This splits 1) above. It will be possible to do all the work of populating the quiz attempt and save that as a 'Created' attempt. Then, when the student clicks Start attempt, we only need to change quiz_attempt.state = 'inprogress' and quiz_attempt.timestart.
- Submitted: This splits 2) above. When the student clicks Submit all and finished, then we will just set quiz_attempt.state ='submitted' and quiz_attempt.timefinish. Then only later (either on cron, or if someone tries to access the review page) will we do the processing to ensure that each question in the attempt is finished.
To support those low-level changes, we will need to:
- All the quiz UI will need to be reviewed to ensure attempts in these states are handled and displayed appropriately. (I don't think this is a big deal.)
- Related to the Created state, we will want to add some UI (probably in quiz_overview report) to pre-create attempts for all or selected students.
- There is a subtle detail. The start time is also stored in each question attempt, and it is stored when the quiz attempt is created. This is not really ideal anyway. E.g. for analytics, in a multipage quiz, that does not say when the student first saw that particual question. Therefore, I think the best thing to do here is to change the question system so that new question_attempst are created with first step timestamp null, and then that timestamp is set the first time the question is rendered.
Doing this should help greatly smooth out the two biggest peaks in server load when students are making simultaneous quiz attempts.
Note to self: these to docs pages need to be merged, and the obsolete information removed.