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

OptionsBootstrapper is provided via a new SessionValues facility rather than a Param #10827

Merged
merged 4 commits into from
Sep 22, 2020

Conversation

stuhood
Copy link
Member

@stuhood stuhood commented Sep 21, 2020

Problem

As described on #10062: any change to options values (including the CLI specs and passthrough args) currently completely invalidate all @rules that consume Subsystems, because the "identities" (memoization keys) of the involved @rules change. As more heavy lifting has begun to depend on options, this has become more obvious and problematic.

Solution

As sketched in #10062 (comment), move to providing the OptionsBootstrapper (and in future, perhaps much smaller wrappers around the "args" and "env" instead) via a new uncacheable SessionValues intrinsic.

More generally, the combination of Params for values that should affect the identity of a @rule, and SessionValues for values that should not affect the identity of a @rule seems to be a sufficient solution to the problem described on #6845. The vast majority of values consumed by @rules should be computed from Params, so it's possible that the env/args will be the only values we ever provide via SessionValues: TBD.

Result

The case described in #10062 (comment) no longer invalidates the consumers of Subsystems, and in general, only the Subsystems that are affected by an option change should be invalidated in memory (although: #10834).

Fixes #10062 and fixes #6845.

[ci skip-build-wheels]

@stuhood stuhood changed the title OptionsBootstrapper is constructed from an uncacheable singleton rather being a param OptionsBootstrapper is constructed from an uncacheable singleton rather being a Param Sep 21, 2020
[ci skip-rust]

[ci skip-build-wheels]
…Session, and is uncacheable.

[ci skip-build-wheels]
@stuhood stuhood force-pushed the stuhood/ob-as-uncacheable branch from 63f29c7 to 434bcfe Compare September 22, 2020 21:00
[ci skip-build-wheels]
@stuhood stuhood force-pushed the stuhood/ob-as-uncacheable branch from 434bcfe to a40a6b6 Compare September 22, 2020 22:11
# Building wheels and fs_util will be skipped. Delete if not intended.
[ci skip-build-wheels]
@stuhood stuhood marked this pull request as ready for review September 22, 2020 23:20
Comment on lines +146 to +154
# TODO: Update all callsites to pass this explicitly via session values.
session = self.scheduler
for value in inputs:
if type(value) == OptionsBootstrapper:
session = self.scheduler.scheduler.new_session(
build_id="buildid_for_test",
should_report_workunits=True,
session_values=SessionValues({OptionsBootstrapper: value}),
)
Copy link
Member Author

Choose a reason for hiding this comment

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

Note: because this hack is quite tiny, I punted on actually changing the TestBase and RuleRunner APIs yet to allow for passing/setting SessionValues. If folks are ok with doing this as a followup, that would be my preference.

Copy link
Contributor

Choose a reason for hiding this comment

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

What's the plan for when to followup? My concern is our documentation; we have users who are starting to write tests for their plugins. We say it's Alpha and we'll make changes, but still helpful to fix before too much code is written.

Fwit, I'm happy to help with this fix.

@stuhood
Copy link
Member Author

stuhood commented Sep 22, 2020

Commits should be reviewed independently.

QueryRule(
CreatedAWSLambda, (PythonAwsLambdaFieldSet, OptionsBootstrapper, PantsEnvironment)
),
QueryRule(CreatedAWSLambda, (PythonAwsLambdaFieldSet, PantsEnvironment)),
Copy link
Contributor

Choose a reason for hiding this comment

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

Should PantsEnvironment become a SessionValue in a followup?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes it should!

Copy link
Contributor

Choose a reason for hiding this comment

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

That'll be wonderful to not have to have users need to fiddle with this during test setup. And an API like this would be nice and declarative:

rule_runner.set_env_var("FOO", "val")

Comment on lines +47 to +48
# TODO: Once the OptionsBootstrapper has been removed from all relevant QueryRules, this lookup
# should be extracted into a separate @rule.
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like they are all removed. Is this still accurate?

Copy link
Member Author

Choose a reason for hiding this comment

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

This can be fixed now: will push another commit.

Copy link
Member Author

Choose a reason for hiding this comment

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

Since this is green, will follow up to fix this first thing tomorrow.

@@ -0,0 +1,19 @@
# Copyright 2016 Pants project contributors (see CONTRIBUTORS.md).
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be in engine/internal? The question is mostly if we expect to document the type SesssionValues and we expect plugin authors to directly import the value. Generally, this gets abstracted from them fwict.

Copy link
Member Author

Choose a reason for hiding this comment

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

It might depend what API we end up with for RuleRunner/TestBase...? I guess it's unlikely that the actual SessionValues type would be exposed in that API though.

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess it's unlikely that the actual SessionValues type would be exposed in that API though.

Yeah, I suspect it's too low level. We can also always "promote" the API to be public if we realize it's relevant. It's harder to demote it to private.

Comment on lines +146 to +154
# TODO: Update all callsites to pass this explicitly via session values.
session = self.scheduler
for value in inputs:
if type(value) == OptionsBootstrapper:
session = self.scheduler.scheduler.new_session(
build_id="buildid_for_test",
should_report_workunits=True,
session_values=SessionValues({OptionsBootstrapper: value}),
)
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the plan for when to followup? My concern is our documentation; we have users who are starting to write tests for their plugins. We say it's Alpha and we'll make changes, but still helpful to fix before too much code is written.

Fwit, I'm happy to help with this fix.

# TODO: Update all callsites to pass this explicitly via session values.
session = self.scheduler
for value in inputs:
if type(value) == OptionsBootstrapper:
Copy link
Contributor

Choose a reason for hiding this comment

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

should you then pop this value from the inputs?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yea, you could. It's unused now.

@Eric-Arellano
Copy link
Contributor

Thanks! I'm excited for the improvement from this change. The overall design looks good, including your sketch for the RuleRunner API.

@stuhood stuhood changed the title OptionsBootstrapper is constructed from an uncacheable singleton rather being a Param OptionsBootstrapper is provided via a new SessionValues facility rather than a Param Sep 22, 2020
@stuhood stuhood merged commit f4763dd into pantsbuild:master Sep 22, 2020
@stuhood stuhood deleted the stuhood/ob-as-uncacheable branch September 22, 2020 23:43
Eric-Arellano added a commit that referenced this pull request Sep 25, 2020
As of #10827, options are now set up through a new `SessionValues` mechanism. This means that our tests should no longer be passing `OptionsBootstrapper` as a `Param` anymore.

Instead, we must mutate the `SchedulerSession` when setting options. We surface a new entry-point `.set_options()`, which will change the options for the life of the `RuleRunner` instance.

```python
rule_runner.set_options(["--pants-ignore=['foo']"])
```

`RuleRunner` already was high on mutation, such as `rule_runner.create_file()` mutating the build root. This is why we encourage using Pytest fixtures to ensure each test is a new instance.

A followup will move `PantsEnvironment` to a `SessionValue`.

[ci skip-rust]
[ci skip-build-wheels]
Eric-Arellano added a commit that referenced this pull request Sep 25, 2020
As introduced in #10827, this is a more correct modeling for reading the environment variables. It will result in less invalidation of Pantsd.

Likewise, we can extend our `rule_runner.set_options()` method introduced in #10859 to simplify how tests change the `PantsEnvironment`.

[ci skip-rust]
[ci skip-build-wheels]
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.

Performance tuning for inference during test iteration Minimize Param usage in Task identities
2 participants