Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LUI-198: Optimize patient dashboard loading by implementing pagination for observations #209

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

ODORA0
Copy link
Member

@ODORA0 ODORA0 commented Nov 13, 2024

Add pagination for patient observations in dashboard

Description:

  • Added pagination to optimize patient observations loading in the dashboard
  • Implemented configurable page size through global properties (default: 50)
  • Added pagination metadata to support UI implementation

Previously, the dashboard would load all patient observations at once, causing
performance issues for patients with many observations. This change:

  • Loads observations in configurable page sizes
  • Allows navigation through URL parameters (?page=0&pageSize=50)
  • Improves dashboard loading performance

Testing:

  • Test with patients having large numbers of observations

Ticket: https://openmrs.atlassian.net/browse/LUI-198

@ODORA0 ODORA0 marked this pull request as ready for review November 21, 2024 10:11
@dkayiwa
Copy link
Member

dkayiwa commented Nov 25, 2024

Did you get a chance to take a look at this? https://openmrs.atlassian.net/wiki/spaces/docs/pages/25477199/Pull+Request+Tips

@ODORA0 ODORA0 changed the title (Enhancement) Optimize patient dashboard loading by implementing pagination for observations LUI-198: Optimize patient dashboard loading by implementing pagination for observations Nov 26, 2024
@ODORA0
Copy link
Member Author

ODORA0 commented Nov 26, 2024

@dkayiwa please review again

@dkayiwa
Copy link
Member

dkayiwa commented Nov 26, 2024

Can we also include the ticket id in the commit message?

Integer page = getPageParameter(request);
Integer pageSize = getPageSizeParameter(request, as);

// Get all observations
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For each time that one moves through the pages, you are still fetching and loading all the patient's observations in memory. My impression was that you would load in memory only those observations for the current page.

@ODORA0 ODORA0 requested a review from dkayiwa December 2, 2024 05:34
boolean includeVoided = false;

// Get observations for the current page
List<Obs> paginatedObs = Context.getObsService().getObservations(persons, encounters, questions,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though the comment says get observations for the current page, i do not seen anything in the getObservations method call that does so. Was it just a typo?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooh yeah, my bad the getObservations() method doesn't have parameters for offset/limit pagination, let me remove that comment

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So then, shall we then have any dashboard loading optimisation if the method loads all of them in memory?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I critically looked at the ObsService interface, didn't notice that it lacks proper pagination parameters (offset/limit). Maybe this should be done as a DAO level implementation so we can have a DB level pagination support, but I would think of doing it this way as well i.e. we can use an existing API features like mostRecentN to limit initial load like so

Suggested change
List<Obs> paginatedObs = Context.getObsService().getObservations(persons, encounters, questions,
List<Obs> paginatedObs = Context.getObsService().getObservations(
persons,
null,
null,
null,
null,
null,
Collections.singletonList("obsDatetime desc"),
pageSize, // mostRecentN - only fetch what we need
null,
null,
null,
false
);

or using date filtering

Suggested change
List<Obs> paginatedObs = Context.getObsService().getObservations(persons, encounters, questions,
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, -30);
Date thirtyDaysAgo = cal.getTime();
List<Obs> recentObs = Context.getObsService().getObservations(
persons,
null,
null,
null,
null,
null,
sort,
null,
null,
thirtyDaysAgo,
new Date(),
false
);

Your thoughts @dkayiwa

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Limiting the number of loaded obs with mostRecentN makes lots of sense to me. For as long as your use case allows it. That is, as long as you are aware that it behaves differently from page size in the sense that the rest of the obs will never be fetched.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay!
@eudson Any thoughts on this, is it acceptable to only show the most recent observations?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants