-
Notifications
You must be signed in to change notification settings - Fork 59
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
Add async processing for patient bulk uploads #4722
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm! thanks for updating the tests for batching too. I had a comment about the final call to addPatientsAndPhoneNumbers
not being in a try block but I'm not too worried about that because my email PR will wrap it anyway.
} | ||
} | ||
|
||
personService.addPatientsAndPhoneNumbers(patientsList, phoneNumbersList); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it ok that the batched calls to addPatientsAndPhoneNumbers
are within a try block, but this one is not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is, because that method is not currently configured to throw any exceptions anyway - I think it would just silently fail.
@@ -121,7 +123,10 @@ public CompletableFuture<Set<Person>> savePatients(byte[] content, UUID facility | |||
// only increment count after person record is created | |||
patientCount++; | |||
|
|||
if (!patientsList.contains(newPatient)) { | |||
// UGH iI need to change this logic too, because patients could be batched in different |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did you mean to leave this comment in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I certainly did not 😆 Thanks for catching that! Removed
stale review; made requested changes
@zdeveloper when you get a chance, can you re-review this now that the naive batching changes are in? I'm pushing this PR forward per Emma's instructions while she's out. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚢
Sorry @rin-skylight! Promise this is the last review request, just addressed some feedback from Zedd. |
Kudos, SonarCloud Quality Gate passed! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛳️ Bringing in the fleet of ships... 😆
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! thank you for all your hard work on this! Its gonna save us so much time!
This PR however will break local testing without okta. As you know, testing a patients file is done locally for PHI reasons.
@emmastephenson @georgehager Please make a ticket to address the changes needed for DemoOktaRepository
to get this working locally without okta since many people on the team run their local dev without okta.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Tested locally and on dev7. Thank you for all your work on this emma and george!!! 😹
@georgehager I also created the ticket for the request Zedd made above: https://app.zenhub.com/workspaces/simplereport-growth--engagement-605b43a6ceb92c000f86279a/issues/gh/cdcgov/prime-simplereport/4900
Feel free to use this or discard/edit as needed!!
BACKEND PULL REQUEST
Related Issue
Changes Proposed
Additional Information
There are two main changes required to get
async
working.1. Change the security context to
INHERITABLETHREADLOCAL
.This means any new threads spawned will inherit the security context of the parent thread. This is required because we need the security context in
PatientBulkUploadServiceAsync
to verify that the user has permissions to call the method.MODE_THREADLOCAL
, the defaultINHERITABLETHREADLOCAL
INHERITABLETHREADLOCAL
2. Add try/catch blocks around
getCurrentOrganizationRoles
andgetCurrentApiUser
forScopeNotActiveException
.This is the source of the dreaded "trying to access request outside of requesting thread" error. In this case it was actually true - we were trying to access
CurrentOrganizationRolesContextHolder
andCurrentApiUserContextHolder
after the initial request had closed. The stack trace on these goes something like the following:PatientBulkUploadServiceAsync
calls_personService.addPatientsAndPhoneNumbers
@Authorization
annotation on that function eventually resolves touserHasPermissions
getCurrentOrganizationRoles
andgetCurrentApiUser
methodsIn my opinion, this is not a security risk because the fallback methods we use to verify permissions (
getCurrentApiUserNoCache
andfetchCurrentOrganizationRoles
) in turn rely on theLoggedInAuthorizationService
to determine roles and permissions. That service relies onSecurityContextHolder
to determine user permissions, which is populated thanks to our niftyMODE_INHERITABLETHREADLOCAL
above. So, if the request is out of scope butSecurityContextHolder
is empty, an exception will eventually be thrown - just later down the stack.TL;DR the ContextHolder pattern is a bit of a cheat to store user permissions inside a request scope, but now that we're operating outside a request scope they don't work. We can get around that to still access user permissions though.
Testing
EDIT: Testing Setup
Backend tests for this were failing for a while on seemingly unrelated tests (
SmsServiceTest
andTestResultUploadTest
). This only happened when the full test suite was run. After in-depth investigation, I can confidently say that this was unrelated to the async changes in this PR and simply brought on as a result of adding anotherSpringBootTest
to our setup - the database ran out of connections with so many tests. (@rin-skylight and I did thoroughly debug the code and ensured that it was properly opening and closing database connections in the new threads).The solution was to add an alteration to the
reset-db
script, to increase the number of available connections from 100 to 500. This fixed the issue when running the test suite both locally and in CI.Checklist for Primary Reviewer
test
,dev
, orpentest
and smoke tested