-
-
Notifications
You must be signed in to change notification settings - Fork 652
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
Handle @rule
cacheability correctly
#8455
Comments
Thinking more about point 1, it does seem we might be able to structure things such that the non-cacheability stays confined to the For example, given class Run(Goal):
"""Runs a binary."""
name = 'run'
@dataclass(frozen=True)
class Binary:
digest: Digest # The digest of a content tree containing the binary.
path: str # The path of the binary within the digested content.
@dataclass(frozen=True)
class AddressAndBinary:
address: BuildFileAddress
binary: Optional[Binary] # If None, target was not a binary target.
@console_rule
def run(console: Console, addresses: BuildFileAddresses, runner: Runner) -> Run:
addresses_and_binaries = yield [Get(AddressAndBinary, Address, addr.to_address()) for addr in addresses]
binaries = [ab for ab in addresses_and_binaries if ab.binary]
if len(binaries) > 1:
console.print_stderr(console.red('Can only one one binary, presented with ...'))
yield Run(-1)
elif len(binaries) == 1:
exit_code = runner.run(binaries[0].binary, options.args)
yield Run(exit_code) |
Will try to take a look at this tomorrow morning, but referencing #6598, which has some thought on this. |
Looking again, I wonder whether this was right: #6598 (comment) "Marking" parameters un-cacheable (or forcing them to be, by preventing an But the advantage of doing this via parameters is that Params already propagate from a caller to a callee, transitively through the graph. So everywhere they travel in the graph they cause non-cachability (and they won't go further than they need to due to rule graph compilation). And that makes non-cachability less error prone. As a thought exercise: the reason I haven't really thought about how un-cacheable parameters would work in the middle of the graph though. If you have a |
If the right unit of cache-ability is parameters and not rules themselves, then maybe the distinction between I don't see a strong difference between requiring (And then once we have a non-cacheable parameter type, I don't see how it matters whether or not the actual subprocess spawning is done in rust or in python, except with regards to signal-handling - but either way, it wouldn't be an engine intrinsic spawning the new process, it would be the non-cacheable type doing it outside the engine). |
But wouldn't checking this / propagating cacheability where it needs to be statically at graph construction time also be just as non error prone? IE: its done once in one bit of unit tested code.
This might make sense. If you run a local process that does no IO, there is no point, so a LocalProcessExecuteRequest would need to take one or more of a Workspace, Console, Network, .... That said - this seems manufactured. There will be no way I can see for the implementation that takes in a LocalProcessExecuteRequest to use the Workspace, Console and Network, they'll just be sentinels hacked in the signature to get un-cacheability. The actual implementation in rust or python will just fork/exec and let that use the local io resources instead of hand-intercepting each one somehow. |
This isn't quite true. The |
In the case on the brain, a local EPR, the type would be ExclusiveConsole and this would be moot. We absolutely do not want concurrency for that set of cases. But in general; ie for logging events of an in progress build, agreed. |
@jsirois : The |
I'm confused comparing:
With:
|
@jsirois : Currently, "only So I was agreeing with you, but indicating that I don't think the Having said that, "side-effecting" and "exclusive" probably go hand in hand. It's possible that all side-effecting parameters should be exclusive, non-cacheable, etc, via a marker trait of some sort? The non-cacheability is handled by banning overrides of |
This is now implemented internally (as |
Me and @jsirois were talking about engine design concerns today as they pertained to the v2 versions of the
./pants run
and./pants repl
goals, and we realized that there are a couple of problems around the cacheable flag on@rule
s that need to solve.Create a type of @rule that is not a @console_rule but is also not cacheable. For instance, many
@console_rule
s that represent top-level goals (such asrun
) will actually proxy to language-specific runner rules (such as a specific python-run@rule
) - and these are not currently marked as non-cacheable. It's unclear whether we want to introduce a 3rd type of@rule
, or whether the distinction between console and non-console@rule
s should really be just a cacheability distinction (perhaps with a name change).Ensuring cacheable rules don't depend on non-cacheable rules. We should do some kind of checking of the graph to make sure that a pants rule developer doesn't accidentally write a cacheable rule that depends on a non-cacheable one. Further, it's not clear if the right response to this is to fail at rule-graph-checking time, or to convert cacheable rules dependent on non-cacheable ones into non-cacheable rules (which "poisons" the graph and might lead to undesirable slowdown - so if we did this, we'd probably want to emit some kind of warning to the console).
Adding cacheable flag on intrinsics. If you look at the
Rule
datastructure defined inengine/src/tasks.rs
, theTask
variant (representing rules defined in python) has thecacheable
boolean, but this doesn't exist onIntrinsic
, representing rust-defined rules. This means that we can't define a rule written in rust as noncacheable.The text was updated successfully, but these errors were encountered: