Skip to content

Commit 4f7150c

Browse files
github-actions[bot]shatzimabdinur
authored
fix(remoteconfig): handle process fork inside remote config client [backport 1.17] (#6778)
Backport de2675a from #6172 to 1.17. When a process fork, the remote config client need to have a new runtime-id and a client-id. However, the state of the configuration should remain the same. ## Checklist - [x] Change(s) are motivated and described in the PR description. - [x] Testing strategy is described if automated tests are not included in the PR. - [x] Risk is outlined (performance impact, potential for breakage, maintainability, etc). - [x] Change is maintainable (easy to change, telemetry, documentation). - [x] [Library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) are followed. If no release note is required, add label `changelog/no-changelog`. - [x] Documentation is included (in-code, generated user docs, [public corp docs](https://github.com/DataDog/documentation/)). - [x] Backport labels are set (if [applicable](../docs/contributing.rst#release-branch-maintenance)) ## Reviewer Checklist - [x] Title is accurate. - [x] No unnecessary changes are introduced. - [x] Description motivates each change. - [x] Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes unless absolutely necessary. - [x] Testing strategy adequately addresses listed risk(s). - [x] Change is maintainable (easy to change, telemetry, documentation). - [x] Release note makes sense to a user of the library. - [x] Reviewer has explicitly acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment. - [x] Backport labels are set in a manner that is consistent with the [release branch maintenance policy](../docs/contributing.rst#release-branch-maintenance) Co-authored-by: Idan Shatz <[email protected]> Co-authored-by: Munir Abdinur <[email protected]>
1 parent d659c3f commit 4f7150c

File tree

3 files changed

+19
-0
lines changed

3 files changed

+19
-0
lines changed

ddtrace/internal/remoteconfig/client.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,11 @@ def base64_to_struct(val, cls):
216216
self._last_error = None # type: Optional[str]
217217
self._backend_state = None # type: Optional[str]
218218

219+
def renew_id(self):
220+
# called after the process is forked to declare a new id
221+
self.id = str(uuid.uuid4())
222+
self._client_tracer["runtime_id"] = runtime.get_runtime_id()
223+
219224
def register_product(self, product_name, pubsub_instance=None):
220225
# type: (str, Optional[PubSub]) -> None
221226
if pubsub_instance is not None:

ddtrace/internal/remoteconfig/worker.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ def start_subscribers(self):
102102
"""Subscribers need to be restarted when application forks"""
103103
self._enable = False
104104
log.debug("[%s][P: %s] Remote Config Poller fork. Starting Pubsub services", os.getpid(), os.getppid())
105+
self._client.renew_id()
105106
for pubsub in self._client.get_pubsubs():
106107
pubsub.restart_subscriber()
107108

tests/internal/remoteconfig/test_remoteconfig.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,22 @@ def test_remote_config_forksafe():
159159
parent_worker = remoteconfig_poller
160160
assert parent_worker.status == ServiceStatus.RUNNING
161161

162+
client_id = remoteconfig_poller._client.id
163+
runtime_id = remoteconfig_poller._client._client_tracer["runtime_id"]
164+
165+
parent_payload = remoteconfig_poller._client._build_payload(None)
166+
167+
assert client_id == parent_payload["client"]["id"]
168+
assert runtime_id == parent_payload["client"]["client_tracer"]["runtime_id"]
169+
162170
if os.fork() == 0:
163171
assert remoteconfig_poller.status == ServiceStatus.RUNNING
164172
assert remoteconfig_poller._worker is not parent_worker
173+
174+
child_payload = remoteconfig_poller._client._build_payload(None)
175+
176+
assert client_id != child_payload["client"]["id"]
177+
assert runtime_id != child_payload["client"]["client_tracer"]["runtime_id"]
165178
exit(0)
166179

167180

0 commit comments

Comments
 (0)