-
Notifications
You must be signed in to change notification settings - Fork 53
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
DATAUP-729 job ts implementation #2960
base: develop
Are you sure you want to change the base?
Conversation
This is looking good! Can you add in functionality such that if there are no updated jobs in response to a request, the backend returns an error? Thanks! |
bf55bdb
to
cd0194c
Compare
This pull request introduces 1 alert when merging cd0194c into c57f696 - view on LGTM.com new alerts:
|
Codecov Report
@@ Coverage Diff @@
## develop #2960 +/- ##
===========================================
+ Coverage 73.25% 73.45% +0.19%
===========================================
Files 36 36
Lines 3903 3906 +3
===========================================
+ Hits 2859 2869 +10
+ Misses 1044 1037 -7
Continue to review full report at Codecov.
|
if msg_type == MESSAGE_TYPE["STATUS"]: | ||
now = time_ns() | ||
for output_state in content.values(): | ||
output_state["last_checked"] = now |
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 not add this timestamp when the job manager is putting together the list of jobs, instead of adding an extra iteration through the job state data 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.
Wasn't sure since the CANCEL_JOBS request also responds with a STATUS message.
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 decided not to filter the STATUS response for CANCEL_JOBS though because I figured in theory they should all get updated, whether successfully or just coming back with 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.
Because everything is asynchronous, the FE doesn't have any way of knowing what triggered a job status message -- whether it was a cancel request, a status request, or the BE job loop. That's why I say it's better to put the timestamp on in the job manager, so that all job state objects that the FE receives have a timestamp on them.
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 one allure of putting everything into JobComm is less tests surgery ... But putting it deep into the stack, at the origin of the STATUS response ds, seems less googly-eyed
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.
Okay I tried putting all the filtering/last_checked logic at the source _construct_job_state_set
but the tests were complaining so I'm abandoning that effort for the sake of time. Is the current placement of the filtering/last_checked good enough?
2d673b4
to
6bbd36d
Compare
SonarCloud Quality Gate failed. 1 Bug No Coverage information |
@@ -32,6 +32,13 @@ def generate_error(job_id, err_type): | |||
return error_strings[err_type] | |||
|
|||
|
|||
def trim_ee2_state(ee2_state, exclude_fields): |
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.
don't we have this code somewhere else?
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.
Yep, Job._trim_ee2_state
. I just got tired of using that in tests when usually we use independent testing functions
ee2_states = self.job_state_data | ||
if params.get("exclude_fields"): | ||
for ee2_state in ee2_states.values(): | ||
trim_ee2_state(ee2_state, params["exclude_fields"]) | ||
if params.get("return_list"): | ||
ee2_states = list(ee2_states.values()) |
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.
Do any of those params ever change? There's only one place where check_workspace_jobs
gets called, and the params are always the same, so...
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.
No, but I thought it might be a good idea to implement the "exclude_fields"
param since here I'm paying closer attention to when state updates are triggered
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.
has adding the exclude_fields
param changed the output of the function?
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.
Well .... now that you mention it ... probably 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.
Today's "good idea to implement" is tomorrow's "why on earth did someone write this?". YAGNI. 😄
job.update_state({}) | ||
self.assertEqual(last_updated, job.last_updated) | ||
|
||
# job has init ee2 state |
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.
This test looks suspiciously spaghetti code-like. Does it need to be done as this long series of transitions or can it be split into separate tests?
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 thought it followed a very similar pattern throughout and so could flow in a single function. The punchline is last_updated
defined at the top never changes throughout these tests. Is there a benefit to making tests methods small?
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.
It's much easier to read, understand, and update/edit a couple of stanzas of code than it is a long series of stanzas. Unless there is a specific need to test a sequence of modifications (e.g. there's something going on elsewhere that changes state as a result of these mods), it's best to make tests as simple as possible to assist future codebase editors and maintainers.
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.
Ah. But what if it's two long stanzas of highly repetitive code? With a common punchline that is accentuated by more repetition?
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.
If it's highly repetitive, it suggests that the repetition could be abstracted out into a function... or that it could be replaced by individual tests that validate the atomic operations involved.
@@ -757,7 +821,7 @@ def test_in_cells__batch__same_cell(self): | |||
batch_job, child_jobs = batch_fam[0], batch_fam[1:] | |||
|
|||
for job in child_jobs: | |||
job.cell_id = "hello" | |||
job._acc_state["job_input"]["narrative_cell_info"]["cell_id"] = "hello" |
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.
Was this the only place you could find where an attribute was changed (other than via the update_state
method)?
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 checked every field in job.__setattr__
that was from the "job_input"
. I didn't check anything in the outer level of the ee2 state.
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.
But update_state
is the only place _acc_state
is mutated
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.
You left a TODO comment about whether the attribute setter was ever used in job.py
-- seems as though you've answered it here, so can delete the comment.
Description of PR purpose/changes
Jira Ticket / Issue
Related Jira ticket: https://kbase-jira.atlassian.net/browse/DATAUP-X
DATAUP-69 Adds a PR template
)Testing Instructions
Dev Checklist:
Updating Version and Release Notes (if applicable)