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

chore(tracing): remove atexit dead code and forksafe dead code #8573

Merged
merged 2 commits into from
Mar 4, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 2 additions & 44 deletions ddtrace/internal/atexit.py
Original file line number Diff line number Diff line change
@@ -16,50 +16,8 @@
log = logging.getLogger(__name__)


if hasattr(atexit, "unregister"):
register = atexit.register
unregister = atexit.unregister
else:
# Hello Python 2!
_registry = [] # type: typing.List[typing.Tuple[typing.Callable[..., None], typing.Tuple, typing.Dict]]

def _ddtrace_atexit():
# type: (...) -> None
"""Wrapper function that calls all registered function on normal program termination"""
global _registry

# DEV: we make a copy of the registry to prevent hook execution from
# introducing new hooks, potentially causing an infinite loop.
for hook, args, kwargs in list(_registry):
try:
hook(*args, **kwargs)
except Exception:
# Mimic the behaviour of Python's atexit hooks.
log.exception("Error in atexit hook %r", hook)

def register(
func, # type: typing.Callable[..., typing.Any]
*args, # type: typing.Any
**kwargs, # type: typing.Any
):
# type: (...) -> typing.Callable[..., typing.Any]
"""Register a function to be executed upon normal program termination"""

_registry.append((func, args, kwargs))
return func

def unregister(func):
# type: (typing.Callable[..., typing.Any]) -> None
"""
Unregister an exit function which was previously registered using
atexit.register.
If the function was not registered, it is ignored.
"""
global _registry

_registry = [(f, args, kwargs) for f, args, kwargs in _registry if f != func]

atexit.register(_ddtrace_atexit)
register = atexit.register
unregister = atexit.unregister


# registers a function to be called when an exit signal (TERM or INT) or received.
26 changes: 1 addition & 25 deletions ddtrace/internal/forksafe.py
Original file line number Diff line number Diff line change
@@ -69,31 +69,7 @@ def unregister(after_in_child):
log.info("after_in_child hook %s was unregistered without first being registered", after_in_child.__name__)


if hasattr(os, "register_at_fork"):
os.register_at_fork(after_in_child=ddtrace_after_in_child, after_in_parent=set_forked)
elif hasattr(os, "fork"):
# DEV: This "should" be the correct way of implementing this, but it doesn't
# work if hooks create new threads.
_threading_after_fork = threading._after_fork # type: ignore

def _after_fork():
# type: () -> None
_threading_after_fork()
if not _soft:
ddtrace_after_in_child()

threading._after_fork = _after_fork # type: ignore[attr-defined]

# DEV: If hooks create threads, we should do this instead.
_os_fork = os.fork

def _fork():
pid = _os_fork()
if pid == 0 and _soft:
ddtrace_after_in_child()
return pid

os.fork = _fork
os.register_at_fork(after_in_child=ddtrace_after_in_child, after_in_parent=set_forked)

_resetable_objects = weakref.WeakSet() # type: weakref.WeakSet[ResetObject]