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

[pantsd] Daemon lifecycle for options changes. #5045

Merged
merged 7 commits into from
Nov 4, 2017

Conversation

kwlzn
Copy link
Member

@kwlzn kwlzn commented Nov 2, 2017

Problem

Currently, if options (from cli args, pants.ini, env vars, rc files et al) affecting the daemon change between runs the daemon does not detect this and will happily run with trapped, stale state.

Solution

Fingerprint the relevant subset of bootstrap options at startup time in the thin client and compare that fingerprint to the one used at launch time for the current pantsd process to determine if the daemon needs to be restarted in advance of the run. This piggy-backs on top of the daemon externalization work.

Result

Fixes #3941.

@kwlzn kwlzn force-pushed the kwlzn/daemon_option_invalidation branch 5 times, most recently from 353ce56 to 1ef31bf Compare November 2, 2017 23:08
@kwlzn kwlzn force-pushed the kwlzn/daemon_option_invalidation branch 2 times, most recently from b43fd8e to df179a8 Compare November 3, 2017 04:38
@kwlzn kwlzn changed the title [WIP] [pantsd] Daemon lifecycle for options changes. [pantsd] Daemon lifecycle for options changes. Nov 3, 2017
@kwlzn kwlzn force-pushed the kwlzn/daemon_option_invalidation branch 2 times, most recently from 5fcc82c to c32408e Compare November 3, 2017 05:30
@kwlzn kwlzn force-pushed the kwlzn/daemon_option_invalidation branch from c32408e to 148e236 Compare November 3, 2017 05:58
sep = sep or self.FINGERPRINT_CMD_SEP
cmdline = cmdline or []
for cmd_part in cmdline:
if cmd_part.startswith('{}='.format(key, sep)):
Copy link
Contributor

Choose a reason for hiding this comment

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

s/=/{}/

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed!

checker.await_pantsd()

# Check for no stray pantsd-runner prcesses.
self.assertFalse(check_process_exists_by_command('pantsd-runner'))
Copy link
Contributor

Choose a reason for hiding this comment

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

There used to be a checker.assert_running() here which feels important

Copy link
Member Author

Choose a reason for hiding this comment

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

checker.await_pantsd() implicitly calls assert_running(), so it should be equivalent.

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 Kris!

:param list exclude_keys: A list of keys to exclude from fingerprint computation.
"""
exclude_keys = set(exclude_keys or [])
acceptable_types = set((bytes, str, list, tuple, dict, int, float, bool, type(None)))
Copy link
Sponsor Member

Choose a reason for hiding this comment

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

Would be good to define this set statically.

Copy link
Member Author

Choose a reason for hiding this comment

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

removed.

hasher.update(k)
v = self.get(k)
assert type(v) in acceptable_types, 'unhashable option type: {}'.format(type(v))
# N.B. This relies on implicit string conversion to do the right thing for
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 should use src/python/pants/option/options_fingerprinter.py to get the correct behaviour for file-options, etc.

Copy link
Member Author

Choose a reason for hiding this comment

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

refactored.

@@ -169,6 +169,20 @@ def watchman_launcher(self):
def is_killed(self):
return self._kill_switch.is_set()

@property
def options_fingerprint(self):
return self._bootstrap_options.sha1(
Copy link
Sponsor Member

Choose a reason for hiding this comment

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

There is already a facility for marking options as fingerprint=True... it would be good to reuse that here if possible:

def get_fingerprintable_for_scope(self, scope, include_passthru=False):

Copy link
Member Author

Choose a reason for hiding this comment

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

great idea. refactored.

def fingerprint(self):
"""The fingerprint of the current process.

:returns: The fingerprint of the running process as read from the process table, ProcessManager
Copy link
Sponsor Member

Choose a reason for hiding this comment

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

It's not clear why this is an OR... a bit more information about why we would check X then Y would be good.

Copy link
Member Author

Choose a reason for hiding this comment

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

added a comment in the docstring.

@stuhood
Copy link
Sponsor Member

stuhood commented Nov 4, 2017

Well, crap. It did not occur to me that so many of these are not already marked fingerprint=True, because they should not affect target fingerprinting.

Can probably completely ignore my feedback. Sorry!

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.

(pre-approving: but you'll need to revert the addition of fingerprint=True)

@kwlzn kwlzn force-pushed the kwlzn/daemon_option_invalidation branch from 826473f to 279678a Compare November 4, 2017 04:35
@kwlzn
Copy link
Member Author

kwlzn commented Nov 4, 2017

@stuhood think I see another way - can mark these daemon=True and parameterize the match key in get_fingerprintable_for_scope() accordingly. pushed a change - let me know what you think.

@kwlzn kwlzn force-pushed the kwlzn/daemon_option_invalidation branch from 279678a to 6115528 Compare November 4, 2017 06:13
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.

This feels cleaner to me then the blacklist of options, so I think it's the right call.

But some sanity check that daemon=True has been passed outside of global options (I think: for any scope other than the global scope ?) would be good. Another thought would be to see whether it's possible to invert the default in this context.

@kwlzn
Copy link
Member Author

kwlzn commented Nov 4, 2017

But some sanity check that daemon=True has been passed outside of global options (I think: for any scope other than the global scope ?) would be good. Another thought would be to see whether it's possible to invert the default in this context.

done and done.

@kwlzn kwlzn force-pushed the kwlzn/daemon_option_invalidation branch 2 times, most recently from 4e4c8e5 to 53f1141 Compare November 4, 2017 08:18
@kwlzn kwlzn force-pushed the kwlzn/daemon_option_invalidation branch from 53f1141 to 5e85274 Compare November 4, 2017 08:23
@kwlzn kwlzn merged commit 1148b07 into pantsbuild:master Nov 4, 2017
kwlzn added a commit to twitter/pants that referenced this pull request Nov 27, 2017
Problem

Currently, if options (from cli args, pants.ini, env vars, rc files et al) affecting the daemon change between runs the daemon does not detect this and will happily run with trapped, stale state.

Solution

Fingerprint the relevant subset of bootstrap options at startup time in the thin client and compare that fingerprint to the one used at launch time for the current pantsd process to determine if the daemon needs to be restarted in advance of the run. This piggy-backs on top of the daemon externalization work.

Result

Fixes pantsbuild#3941.
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.

3 participants