-
Notifications
You must be signed in to change notification settings - Fork 9
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
Introduce createLimitedPromises
wrapper for p-limit
(#326)
#327
Introduce createLimitedPromises
wrapper for p-limit
(#326)
#327
Conversation
limitPromises
wrapper for p-limit
(#326)createLimitedPromises
wrapper for p-limit
(#326)
I will review this some time in late afternoon. |
I did some testing with 400 user enrolling 4 times and in all the time i saw the success. here is the report from that. I might do testing on Monday. |
6b9d0f1
to
1389fc7
Compare
I will review some more by end of day |
const coursesApiPromises = createLimitedPromises<CanvasCourse[] | APIErrorData>( | ||
accountIds.map(a => async () => await this.getAccountCourses(a, queryParams)) | ||
) |
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.
We probably don't have to limit here, since we're just making one (albeit potentially rather large paginated request) for each parent account the user has. It can't be that many, even if they're a sub account admin in several accounts. Especially if we're at 20
for a limit, this won't make much of a difference.
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.
Good thinking on wrapping the concurrency code to Getting courses from an account, I was bit worried if user search by course name Bio
then it might fetch lot of courses and will end up with rate limiting errors, this should take care it
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.
Just to clarify, this is limiting the number of promises for calls of this.getAccountCourses
, so if there were three accounts that someone was a sub-account admin for, that would be three promises. The @kth/canvas-api
library is doing the paging, so that may actually involve multiple calls behind the scenes (probably in sequence?), but for us it's just one promise. Does that make sense? That's why I was saying it was minimal improvement here.
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.
Got it.
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 elected to remove the limiting here. I think it's highly unlikely that anyone would be an admin in >20 sub-accounts. We can reassess if we ever see an edge case scenario.
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 agree
const apiPromises = createLimitedPromises<CanvasCourseSectionBase | APIErrorData>( | ||
sectionIds.map(si => async () => { | ||
const sectionHandler = new SectionApiHandler(requestor, si) | ||
return await sectionHandler.unmergeSection() | ||
}) | ||
) |
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.
See https://github.com/tl-its-umich-edu/canvas-course-manager-next/pull/327/files#r803102325, same logic applies.
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.
Why unmerge has to be wrapped with the concurrency call? since we mostly ever going to do 1 section unmerge at a time
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.
That's fine, I can remove it if you want, I was just looking for feedback on which to remove it from.
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.
Theoretically, someone could do up to 250 using the API, but not likely to ever happen.
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.
Since UI doesn't support bulk unmerge and only one at a time, I believe we can remove it
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.
So you're not worried about direct API calls? This is the DTO for both merge and unmerge: https://github.com/tl-its-umich-edu/canvas-course-manager-next/blob/main/ccm_web/server/src/api/dtos/api.section.ids.dto.ts
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.
Let me check on it one more time and get back to you.
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.
Ok I checked again, even though this is list sectionIds.map
but that list will always have 1 section for unmerge section. So the wrapper for p-limit strictly it is not needed since we are queuing one call. But I will leave this up to you
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'm gonna leave it. My thinking is that the backend logic should reflect what we support in the API, since either the frontend could change, or we may want to use the API directly in some strange customer support scenario. In all other cases where we could have >20 calls, we're using this, so it makes sense to be consistent.
limit: 3, | ||
methods: ['POST', 'GET', 'PUT', 'DELETE'], | ||
statusCodes: got.defaults.options.retry.statusCodes.concat([403]), | ||
calculateDelay: ({ attemptCount, retryOptions, error, computedValue }) => { | ||
const delay = computedValue === 0 ? 0 : 5000 | ||
const delay = computedValue === 0 ? 0 : 2000 |
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 just did this. My thinking is that we initially set these so high as a way to back off from the rate limit, and get all the requests through, but that shouldn't be necessary anymore. We still want retrying behavior for intermittent Canvas errors and such, but lower levels like this should be sufficient.
@pushyamig and @lsloan, I think this is ready for review. Please let me know if any of the cases where I introduced limiting you think it should be removed (fine doing that, just want your input; I weighed in on the cases where it seemed less useful). |
The change seems to be straight forward but affects most features. I did some preliminary testing and review, things looks good! I will go one more round tomorrow and will approve. |
Over all this is a positive change and huge performance improvement and increase customer satisfaction rate. This also means that for Add Non-UM user we could support more that 200 (based on testing). I have my testing report across features This is a go from me, I think just need to resolve some merge conflicts and probably remove the concurrency call with un merge sections |
… use limitPromises, return functions
…ncurrentPromises; remove restraint on generic T
f230f3b
to
762e466
Compare
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.
Nice Work @ssciolla
@pushyamig, thanks for the thorough review! |
The PR aims to resolve #326.
(I'm pretty sure this does the trick, and it kinda feels like magic 🪄 .)
Resource(s):