Skip to content

Commit

Permalink
extract out exiter_as to ExceptionSink and cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
ity committed Apr 24, 2019
1 parent b7af7d3 commit f9b0313
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 61 deletions.
12 changes: 12 additions & 0 deletions src/python/pants/base/exception_sink.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,18 @@ def _handle_signal_gracefully(cls, signum, signame, traceback_lines):
# Exit, printing the output to the terminal.
cls._exit_with_failure(terminal_log_entry)

@classmethod
@contextmanager
def exiter_as(cls, exiter):
"""A contextmanager which temporarily overrides the exiter."""
try:
previous_exiter = cls._exiter if cls._exiter else exiter
cls._exiter = exiter
ExceptionSink.reset_exiter(cls._exiter)
yield cls._exiter
finally:
cls._exiter = previous_exiter
ExceptionSink.reset_exiter(cls._exiter)

# Setup global state such as signal handlers and sys.excepthook with probably-safe values at module
# import time.
Expand Down
44 changes: 12 additions & 32 deletions src/python/pants/bin/daemon_pants_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,27 +261,6 @@ def nailgunned_stdio(cls, sock, env, handle_stdin=True):
) as finalizer:
yield finalizer

@contextmanager
def daemon_exiter(cls, exiter):
"""A contextmanager which temporarily overrides the exiter."""
try:
cls._exiter = exiter
yield exiter
finally:
pass

@contextmanager
def set_exiter(cls, exiter):
"""A contextmanager which temporarily overrides the exiter."""
try:
previous_exiter = cls._exiter
cls._exiter = exiter
ExceptionSink.reset_exiter(exiter)
yield cls._exiter
finally:
cls._exiter = previous_exiter
ExceptionSink.reset_exiter(previous_exiter)

# TODO: there's no testing for this method, and this caused a user-visible failure -- see #7008!
def _raise_deferred_exc(self):
"""Raises deferred exceptions from the daemon's synchronous path in the post-fork client."""
Expand Down Expand Up @@ -348,40 +327,41 @@ def post_fork_child(self):
service.terminate()

# Invoke a Pants run with stdio redirected and a proxied environment.
daemonExiter = DaemonExiter(self._socket)
with self.nailgunned_stdio(self._socket, self._env) as finalizer,\
hermetic_environment_as(**self._env),\
self.set_exiter(daemonExiter) as daemonExiter:
ExceptionSink.exiter_as(self._exiter) as daemon_exiter:
try:
# Setup the Exiter's finalizer.
self._exiter.set_finalizer(finalizer)
daemon_exiter.set_finalizer(finalizer)

# Clean global state.
clean_global_runtime_state(reset_subsystem=True)

# Re-raise any deferred exceptions, if present.
self._raise_deferred_exc()
# Otherwise, conduct a normal run.
runner = LocalPantsRunner.create(
self._exiter,
daemon_exiter,
self._args,
self._env,
self._target_roots,
self._graph_helper,
self._options_bootstrapper
)
runner.run()
# Re-raise any deferred exceptions, if present.
self._raise_deferred_exc()

exit_code = runner.run()
daemon_exiter.exit(exit_code)
except KeyboardInterrupt:
daemonExiter.exit_and_fail('Interrupted by user.\n')
except GracefulTerminationException as e:
daemon_exiter.exit_and_fail('Interrupted by user.\n')
except _GracefulTerminationException as e:
ExceptionSink.log_exception(
'Encountered graceful termination exception {}; exiting'.format(e))
daemonExiter.exit(e.exit_code)
daemon_exiter.exit(e.exit_code)
except Exception:
# TODO: We override sys.excepthook above when we call ExceptionSink.set_exiter(). That
# excepthook catches `SignalHandledNonLocalExit`s from signal handlers, which isn't
# happening here, so something is probably overriding the excepthook. By catching Exception
# and calling this method, we emulate the normal, expected sys.excepthook override.
ExceptionSink._log_unhandled_exception_and_exit()
else:
daemonExiter.exit(PANTS_SUCCEEDED_EXIT_CODE)
daemon_exiter.exit(PANTS_SUCCEEDED_EXIT_CODE)
38 changes: 9 additions & 29 deletions src/python/pants/bin/local_pants_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

import logging
import time
from contextlib import contextmanager

from builtins import object, str

from pants.base.build_environment import get_buildroot
Expand Down Expand Up @@ -84,17 +82,6 @@ def exit(self, result=PANTS_SUCCEEDED_EXIT_CODE, msg=None, *args, **kwargs):
class LocalPantsRunner(object):
"""Handles a single pants invocation running in the process-local context."""

@contextmanager
def set_exiter(self, exiter):
"""A contextmanager which temporarily overrides the exiter."""
previous_exiter = self._exiter if self._exiter else exiter
try:
ExceptionSink.reset_exiter(exiter)
yield
finally:
self._exiter = previous_exiter
ExceptionSink.reset_exiter(self._exiter)

@staticmethod
def parse_options(args, env, setup_logging=False, options_bootstrapper=None):
options_bootstrapper = options_bootstrapper or OptionsBootstrapper.create(args=args, env=env)
Expand Down Expand Up @@ -296,21 +283,14 @@ def _compute_final_exit_code(*codes):
return max_code

def _run(self):
<<<<<<< HEAD
try:
self._maybe_handle_help()

engine_result = self._maybe_run_v2()
goal_runner_result = self._maybe_run_v1()
finally:
=======
self._set_start_time(time.time())

# wrap the outer exiter
local_exiter = LocalExiter(self._run_tracker, self._repro, exiter=self._exiter)
with self.set_exiter(local_exiter):
>>>>>>> 0ffa7ab... add contextmanager'd exiters and change return type of run()
with ExceptionSink.exiter_as(local_exiter):
try:
self._maybe_handle_help()

engine_result = self._maybe_run_v2()
goal_runner_result = self._maybe_run_v1()
finally:
Expand All @@ -321,9 +301,9 @@ def _run(self):
logger.exception(e)
run_tracker_result = PANTS_SUCCEEDED_EXIT_CODE

final_exit_code = self._compute_final_exit_code(
engine_result,
goal_runner_result,
run_tracker_result
)
return final_exit_code
final_exit_code = self._compute_final_exit_code(
engine_result,
goal_runner_result,
run_tracker_result
)
return final_exit_code

0 comments on commit f9b0313

Please sign in to comment.