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
Fix bug where workunit completion was not reported correctly #10277
Conversation
4789b6a
to
74c9f7a
Compare
@@ -454,30 +462,52 @@ impl WorkunitStore { | |||
started.log_workunit_state() | |||
} | |||
|
|||
let sender = self.heavy_hitters_data.msg_tx.lock(); | |||
sender.send(StoreMsg::Started(started.clone())).unwrap(); | |||
if self.rendering_dynamic_ui { |
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 merge this with the above conditional I think?
let mut inner = self.heavy_hitters_data.inner.lock(); | ||
HeavyHittersData::add_started_workunit_to_store(started.clone(), &mut inner); |
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.
Rather than adding this to the store, could the caller hold onto a copy of the workunit until it was completed?
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 that would make the logic overly complicated for no gain - the store already knows how to hold onto a started workunit, and then mark it as complete when the completed version of the workunit arrives.
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.
Hm. I think that I disagree. Writing to the store here would seem to break the abstraction that we enqueue things to be consumed, but otherwise don't acquire the lock on the store. It adds complexity because it violates that abstraction.
Holding onto the workunit between let workunit = ...start_workunit(); ... complete_workunit(workunit)
on the other hand seems to fit into this model just fine, and would likely be less complex?
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.
The locks and queues are concerns internal to WorkunitStore
; callers of WorkunitStore::start_workunit()
and complete_workunit
shouldn't care about what these methods are doing internally. This change would also require the signature of start_workunit
and complete_workunit
to effectively be different depending on whether the dynamic UI was active or not, if I'm understanding your suggestion correctly.
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 change would also require the signature of start_workunit and complete_workunit to effectively be different depending on whether the dynamic UI was active or not, if I'm understanding your suggestion correctly.
I think that you could do this in all cases, and it would remove the dict/map lookup to figure out "which" workunit you are finishing. It might even be more efficient because of that. But also, any caller using with_workunit
(which we should recommend!) wouldn't have to worry about it at all.
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.
And it would probably also fix #10249 ...?
4fade71
to
1e130f9
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.
Thanks! This looks great.
'src/python/pants/engine/internals:tests', | ||
'src/python/pants/testutil:int-test', |
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.
Nit: Neither of these should be necessary anymore! Huzzah.
@Eric-Arellano : maybe this will be a worth a warning at some point... EDIT: ... maybe not though. Complicated by sub-targets I suppose.
@@ -70,3 +70,14 @@ python_integration_tests( | |||
sources = ['test_prelude_integration.py'], | |||
uses_pants_run=True, | |||
) | |||
|
|||
python_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.
This should be python_integration_tests(
. Then remove the tag
and remove 'src/python/pants/testutil:int-test'
. Also, you should be able to remove 'src/python/pants/engine/internals:tests'
due to dep inference.
|
||
python_tests( | ||
name = 'log_output_integration', | ||
sources = [ 'log_output_integration_test.py' ], |
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.
Nit
sources = [ 'log_output_integration_test.py' ], | |
sources = ['log_output_integration_test.py'], |
|
||
return tmpdir_relative | ||
|
||
def test_completed_log_output(self): |
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.
def test_completed_log_output(self): | |
def test_completed_log_output(self) -> None: |
88db7a9
to
caeac0d
Compare
caeac0d
to
48bfe03
Compare
…ild#10277) ### Problem pantsbuild#10179 had the effect of changing the architecture of the workunit store so that when workunits were started and completed, the methods responsible for these tasks would push them onto a mpsc queue, and they would only actually be added to the store when one of the methods that handed them pulled the workunits off the queue. This is fine when the dynamic UI is running, because the `heavy_hitters` method will be running constantly, and therefore logging workunit completion messages. However, in the `--no-dynamic-ui` case, `heavy_hitters` doesn't run, and therefore nothing handles the workunits on the queue, ### Solution The workunit store is already aware of whether the dynamic UI is running or not, so this commit has the workunit completion method check this flag. If it's set, we send workunits over the mpsc queue, and expect them to be added to the store (a locking operation) by `heavy_hitters`, which needs to grab the lock anyway. When the dynamic UI is not running, the workunit add method doesn't use the heavy hitters mpsc queue at all, and just emits the display message for the workunit completion. Additionally, a new integration test is added to test that these workunit completion log messages get printed. ### Result Fixes pantsbuild#10274
Problem
#10179 had the effect of changing the architecture of the workunit store so that when workunits were started and completed, the methods responsible for these tasks would push them onto a mpsc queue, and they would only actually be added to the store when one of the methods that handed them pulled the workunits off the queue. This is fine when the dynamic UI is running, because the
heavy_hitters
method will be running constantly, and therefore logging workunit completion messages. However, in the--no-dynamic-ui
case,heavy_hitters
doesn't run, and therefore nothing handles the workunits on the queue,Solution
The workunit store is already aware of whether the dynamic UI is running or not, so this commit has the workunit completion method check this flag. If it's set, we send workunits over the mpsc queue, and expect them to be added to the store (a locking operation) by
heavy_hitters
, which needs to grab the lock anyway. When the dynamic UI is not running, the workunit add method doesn't use the heavy hitters mpsc queue at all, and just emits the display message for the workunit completion. Additionally, a new integration test is added to test that these workunit completion log messages get printed.Result
Fixes #10274