From b99e67c21f8c9818dca7df84764ee9b5a4afd892 Mon Sep 17 00:00:00 2001 From: Dennis Kliban Date: Wed, 18 Feb 2026 10:17:13 -0500 Subject: [PATCH] Moves API heartbeat to it's own thread. fixes: #7315 --- CHANGES/7315.bugfix | 1 + pulpcore/app/entrypoint.py | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 CHANGES/7315.bugfix diff --git a/CHANGES/7315.bugfix b/CHANGES/7315.bugfix new file mode 100644 index 0000000000..2c76b9c985 --- /dev/null +++ b/CHANGES/7315.bugfix @@ -0,0 +1 @@ +Fixed bug where API process would miss heartbeats during long uploads. diff --git a/pulpcore/app/entrypoint.py b/pulpcore/app/entrypoint.py index 9f7f1d43a2..ff197c874c 100644 --- a/pulpcore/app/entrypoint.py +++ b/pulpcore/app/entrypoint.py @@ -2,6 +2,8 @@ from logging import getLogger import os import sys +import threading +import time import click import django @@ -22,9 +24,18 @@ class PulpApiWorker(SyncWorker): + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.heartbeat_thread = None + def notify(self): super().notify() - self.heartbeat() + + def _heartbeat_loop(self): + while self.alive: + self.heartbeat() + time.sleep(self.heartbeat_interval) def heartbeat(self): try: @@ -76,6 +87,13 @@ def init_process(self): logger.error(f"An API app with name {self.name} already exists in the database.") exit(Arbiter.WORKER_BOOT_ERROR) + # Store heartbeat interval for the heartbeat thread + self.heartbeat_interval = settings.API_APP_TTL // 3 + + # Start heartbeat thread before entering the main loop + self.heartbeat_thread = threading.Thread(target=self._heartbeat_loop, daemon=True) + self.heartbeat_thread.start() + super().init_process() def run(self):