Skip to content
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

Merged
merged 5 commits into from Jul 14, 2020

Conversation

gshuflin
Copy link
Contributor

@gshuflin gshuflin commented Jul 7, 2020

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

@@ -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 {
Copy link
Sponsor Member

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?

Comment on lines 469 to 468
let mut inner = self.heavy_hitters_data.inner.lock();
HeavyHittersData::add_started_workunit_to_store(started.clone(), &mut inner);
Copy link
Sponsor Member

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?

Copy link
Contributor Author

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.

Copy link
Sponsor Member

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?

Copy link
Contributor Author

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.

Copy link
Sponsor Member

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.

Copy link
Sponsor Member

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 ...?

@gshuflin gshuflin force-pushed the fix_workunit_start_bug branch 2 times, most recently from 4fade71 to 1e130f9 Compare July 10, 2020 00:35
Copy link
Sponsor Member

@stuhood stuhood left a 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.

Comment on lines 78 to 79
'src/python/pants/engine/internals:tests',
'src/python/pants/testutil:int-test',
Copy link
Sponsor Member

@stuhood stuhood Jul 10, 2020

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(
Copy link
Contributor

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' ],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit

Suggested change
sources = [ 'log_output_integration_test.py' ],
sources = ['log_output_integration_test.py'],


return tmpdir_relative

def test_completed_log_output(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def test_completed_log_output(self):
def test_completed_log_output(self) -> None:

@gshuflin gshuflin force-pushed the fix_workunit_start_bug branch 6 times, most recently from 88db7a9 to caeac0d Compare July 14, 2020 01:56
@gshuflin gshuflin merged commit ee0cba3 into pantsbuild:master Jul 14, 2020
Eric-Arellano pushed a commit to Eric-Arellano/pants that referenced this pull request Jul 15, 2020
…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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Workunit completion not logged on master
3 participants