Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 observability to QuartzJob #461
Add async observability to QuartzJob #461
Changes from 9 commits
efbd2ee
426724e
754d398
9269486
77387a0
4eac46c
a0ab15e
4869a46
8a5c0d7
5066e04
2d5f6f0
369523f
3df240c
e1499f3
06daaad
f84030b
fbefd8a
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
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.
How feasible is it to start an
Observation
in a separate class - and a separate Java thread - and update theObservation
here?We queue the job over in ImportService.java:
terra-workspace-data-service/service/src/main/java/org/databiosphere/workspacedataservice/service/ImportService.java
Line 85 in c6eb725
and if we wanted to track timing between
QUEUED
andRUNNING
status, we'd need to start the Observation over there.I am totally fine answering this question sometime after this PR merges. What's in this PR as-is is useful and adds value, so it's worth it on its own.
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 call @davidangb this is actually the spirit behind the measurement, which is to know how long the customer has to wait, so I'm in favor of this. Ok to defer to another PR though if you just want to land this one @ashanhol
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 actually had this exact thought when doing this, but couldn't quite figure out how to "pass" an observation from one class to another. I'm happy to make a ticket to think about it further.
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.
https://broadworkbench.atlassian.net/browse/AJ-1568
This file was deleted.
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.
could you add a test for a failing job that looks for
.hasLowCardinalityKeyValue("outcome", "failure")
? You probably need to modifyTestableQuartzJob
or create something new thatextends QuartzJob
but throws an error inexecuteInternal
.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'm losing my mind here. In this current test implementation I have the execute function wrapped in a
assertThrows
, and it fails because it says it doesn't throw anything. But if I get rid ofassertThrows
it totally does. I feel like I'm missing something obviousThere 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 @jladieu and I figured this out, and it's confusing. We have two JobExecutionExceptions, one from Quartz and one we define. The one we define extends RuntimeException and therefore doesn't need to be caught/handled, but the quartz one does. QuartzJob.execute throws a org.quartz.JobExecutionException (and therefore needs the
throws org.quartz.JobExecutionException
in the method signature), but all our custom jobs throw various RuntimeException ones. So I had the right idea having the TestQuartzJob throw our custom one but it made writing this test VERY confusingThere 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.
Maybe this explanation helps to explain …
The typical data flow is:
execute()
method and runs that method when it kicks off a jobexecute()
method inQuartzJob
.QuartzJob.execute()
wraps and calls theexecuteInternal()
method defined in subclasses such asTdrManifestQuartzJob
orPfbQuartzJob
QuartzJob.execute()
!!catches any exceptions thrown byexecuteInternal
!!. On catch, it marks the job as failed and swallows the exception so Quartz can mark its job as complete.In this test:
TestableQuartzJob
subclass ofQuartzJob
executeInternal()
!!QuartzJob.execute()
wrapper properly catches the error thrown fromexecuteInternal()
, marks the job as failed, registers metrics, and swallows the error.So, it's expected that when this test calls
TestableQuartzJob(...).execute
, it will not throw an error.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.
Yeah, I figured it out eventually. I personally didn't know that RuntimeException had different behavior than regular Exception and that required some compiler fighting and extra confusion with the namespaces.