Skip to content

Conversation

thomasleese
Copy link
Contributor

@thomasleese thomasleese commented Mar 25, 2025

This introduces a new model, PatientSession::VaccinationStatus, which stores the vaccination status of a patient-programme pair in the database so it can queried and rendered quickly. Locally, I'm seeing the session outcomes page on programmes with 50,000 patients load almost instantly even when filtering on statuses. The session overview page has a slight improvement, but that will only load quickly once the other statuses are cached.

I've decided not to implement a state machine as had been previously discussed, but this could be built on top of this change to enhancement the functionality. For now, this effectively caches the existing logic that runs on the fly to the database.

I've also decided not to implement this using Rails callbacks and instead be explicit where the status is refreshed. This allows us to optimise for bulk refreshes, as is necessary when adding new programmes to sessions, running the seeds, or generally updating the status of an entire session.

To support the vaccination status of the session changing each day (when the registration status of the patient changes), this introduces a nightly job which runs and updates the statuses to ensure they are up to date when the day changes. This introduces a potential risk in case the status updater job fails. There is one scenario to call out if this rare scenario happens:

If a patient is marked as absent, the session outcome for the patient will continue to show as "absent from session" the next day until either the nightly job runs again, another status of the patient changes, or the patient is marked as absent or present again.

This follows up from #3272 which applies the same to the programme status.

@thomasleese thomasleese added the performance Improving performance label Mar 25, 2025
@thomasleese thomasleese added this to the v2.1.2 milestone Mar 25, 2025
@thomasleese thomasleese changed the base branch from main to cache-programme-status March 25, 2025 10:36
@thomasleese thomasleese force-pushed the cache-programme-status branch 2 times, most recently from a8e70b1 to fb30f06 Compare March 25, 2025 18:10
@thomasleese thomasleese force-pushed the cache-session-status branch from 27c13ad to a55a184 Compare March 25, 2025 18:44
@thomasleese thomasleese marked this pull request as ready for review March 25, 2025 18:44
@thomasleese thomasleese force-pushed the cache-session-status branch from a55a184 to 7f4d581 Compare March 25, 2025 19:14
@thomasleese thomasleese force-pushed the cache-programme-status branch from fb30f06 to 13adedc Compare March 25, 2025 20:00
@thomasleese thomasleese force-pushed the cache-session-status branch from 7f4d581 to 44224ea Compare March 25, 2025 20:01
@thomasleese thomasleese force-pushed the cache-programme-status branch from 13adedc to 63da35a Compare March 25, 2025 22:09
@thomasleese thomasleese force-pushed the cache-session-status branch from 44224ea to 10ab6c3 Compare March 25, 2025 22:22
@thomasleese thomasleese force-pushed the cache-programme-status branch 4 times, most recently from bb40682 to 19bd43b Compare March 26, 2025 11:15
@thomasleese thomasleese force-pushed the cache-session-status branch from 10ab6c3 to 31f93ae Compare March 26, 2025 11:23
@thomasleese thomasleese force-pushed the cache-session-status branch from 31f93ae to 34f95c7 Compare March 26, 2025 12:35
@thomasleese thomasleese force-pushed the cache-session-status branch from 34f95c7 to 80cc26d Compare March 26, 2025 12:37
@thomasleese thomasleese force-pushed the cache-session-status branch from 80cc26d to 3cc744d Compare March 26, 2025 12:41
@thomasleese thomasleese force-pushed the cache-session-status branch from cf96582 to 3fe53b2 Compare March 28, 2025 16:51
@thomasleese thomasleese force-pushed the cache-programme-status branch from 34c6886 to e086f92 Compare March 28, 2025 17:03
@thomasleese thomasleese force-pushed the cache-session-status branch from 3fe53b2 to e70bb04 Compare March 28, 2025 17:04
@thomasleese thomasleese force-pushed the cache-programme-status branch from e086f92 to 45ae142 Compare March 28, 2025 17:12
@thomasleese thomasleese force-pushed the cache-session-status branch from e70bb04 to fc8cf0b Compare March 28, 2025 17:12
@thomasleese thomasleese force-pushed the cache-programme-status branch from 45ae142 to 747650e Compare March 31, 2025 13:24
@thomasleese thomasleese force-pushed the cache-session-status branch from fc8cf0b to a2917e4 Compare March 31, 2025 13:24
Base automatically changed from cache-programme-status to v2.1.2-wip March 31, 2025 13:47
This removes usage of the `all` and `latest` methods of the
`SessionOutcome` in preparation for the class being replaced with a
model storing a cached version of the status.
This creates a new model that will represent the vaccination status
of a patient/programme pair so the value can be queried in the
database directly rather than needing to generate the status on the
fly each time.
This adds a method which refreshes the status of a patient-programme
pair to be used in various other parts of the service. This is the main
logic that replaces the `SessionOutcome` class, although the logic
itself should be the same.
This updates the factories to create instances of the new
`PatientSession::VaccinationStatus` model to ensure the tests are
running in representative database.
This updates the various parts of the code that relied on the
`SessionOutcome` class to determine the consent status of a patient to
instead use the new `PatientSession::VaccinationStatus` model with the
status cached.
This can be safely removed as it's no longer being used and has been
replaced with the `PatientSession::VaccinationStatus` model.
This adds a job which handles the process of updating the status of
patients in the background so we can run it on a schedule or for larger
sessions.
Often the session can have lots of patients in and this can be slow. To
ensure the user doesn't see this slowdown, we can queue the job to run
in the background and the statuses will be updated shortly.
This is necessary as the registration status of a patient is tied to the
current day and needs to reset the next day when there may no longer be
a session date on that day.
@thomasleese thomasleese force-pushed the cache-session-status branch from 7d03546 to 4fe227f Compare March 31, 2025 17:17
@tvararu tvararu temporarily deployed to mavis-pr-3273 March 31, 2025 17:17 Inactive
Copy link

@thomasleese thomasleese merged commit 9f552b2 into v2.1.2-wip Apr 1, 2025
11 checks passed
@thomasleese thomasleese deleted the cache-session-status branch April 1, 2025 05:20
thomasleese added a commit that referenced this pull request Apr 1, 2025
This introduces a new model, `PatientSession::RegistrationStatus`, which
stores the vaccination status of a patient-session date pair in the
database so it can queried and rendered quickly. Locally, I'm seeing the
register outcomes page on programmes with 50,000 patients load almost
instantly even when filtering on statuses. The session overview page has
a slight improvement, but that will only load quickly once the other
statuses are cached.

I've decided not to implement a state machine as had been previously
discussed, but this could be built on top of this change to enhancement
the functionality. For now, this effectively caches the existing logic
that runs on the fly to the database.

I've also decided not to implement this using Rails callbacks and
instead be explicit where the status is refreshed. This allows us to
optimise for bulk refreshes, as is necessary when adding new programmes
to sessions, running the seeds, or generally updating the status of an
entire session.

This follows up from
#3273 which
applies the same to the session status.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Improving performance
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants