MCPcopy Index your code
hub / github.com/borgbackup/borg / daemonizing

Function daemonizing

src/borg/helpers/process.py:66–147  ·  view source on GitHub ↗

Like daemonize(), but as a context manager. The with-body is executed in the background process, while the foreground process survives until the body is left or the given timeout is exceeded. In the latter case a warning is reported by the foreground. Context variable is (old_id

(*, timeout=5, show_rc=False)

Source from the content-addressed store, hash-verified

64
65@contextlib.contextmanager
66def daemonizing(*, timeout=5, show_rc=False):
67 """Like daemonize(), but as a context manager.
68
69 The with-body is executed in the background process,
70 while the foreground process survives until the body is left
71 or the given timeout is exceeded. In the latter case a warning is
72 reported by the foreground.
73 Context variable is (old_id, new_id) get_process_id tuples.
74 An exception raised in the body is reported by the foreground
75 as a warning as well as propagated outside the body in the background.
76 In case of a warning, the foreground exits with exit code EXIT_WARNING
77 instead of EXIT_SUCCESS.
78 """
79 with _daemonize() as (old_id, new_id):
80 if new_id is None:
81 # The original / parent process, waiting for a signal to die.
82 logger.debug("Daemonizing: Foreground process (%s, %s, %s) is waiting for background process..." % old_id)
83 exit_code = EXIT_SUCCESS
84 # Indeed, SIGHUP and SIGTERM handlers should have been set on archiver.run(). Just in case...
85 with (
86 signal_handler("SIGINT", raising_signal_handler(KeyboardInterrupt)),
87 signal_handler("SIGHUP", raising_signal_handler(SigHup)),
88 signal_handler("SIGTERM", raising_signal_handler(SigTerm)),
89 ):
90 try:
91 if timeout > 0:
92 time.sleep(timeout)
93 except SigTerm:
94 # Normal termination; expected from grandchild, see 'os.kill()' below
95 pass
96 except SigHup:
97 # Background wants to indicate a problem; see 'os.kill()' below,
98 # log message will come from grandchild.
99 exit_code = EXIT_WARNING
100 except KeyboardInterrupt:
101 # Manual termination.
102 logger.debug("Daemonizing: Foreground process (%s, %s, %s) received SIGINT." % old_id)
103 exit_code = EXIT_SIGNAL_BASE + 2
104 except BaseException as e:
105 # Just in case...
106 logger.warning(
107 "Daemonizing: Foreground process received an exception while waiting:\n"
108 + "".join(traceback.format_exception(e.__class__, e, e.__traceback__))
109 )
110 exit_code = EXIT_WARNING
111 else:
112 logger.warning("Daemonizing: Background process did not respond (timeout). Is it alive?")
113 exit_code = EXIT_WARNING
114 finally:
115 # Before terminating the foreground process, honor --show-rc by logging the rc here as well.
116 # This is mostly a consistency fix and not very useful considering that the main action
117 # happens in the daemon process.
118 if show_rc:
119 from ..helpers import do_show_rc
120
121 do_show_rc(exit_code)
122 # Don't call with-body, but die immediately!
123 # return would be sufficient, but we want to pass the exit code.

Callers 2

mountMethod · 0.85
mountMethod · 0.85

Calls 9

_daemonizeFunction · 0.85
signal_handlerFunction · 0.85
raising_signal_handlerFunction · 0.85
do_show_rcFunction · 0.85
_ExitCodeExceptionClass · 0.85
debugMethod · 0.80
sleepMethod · 0.80
warningMethod · 0.80
errorMethod · 0.80

Tested by

no test coverage detected