Skip to content
Open
Show file tree
Hide file tree
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
28 changes: 28 additions & 0 deletions clients/python/src/taskbroker_client/drain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import argparse
import time
from pathlib import Path

from taskbroker_client.constants import DEFAULT_WORKER_DRAIN_FILE_PATH


def drain(seconds: float, path: str = DEFAULT_WORKER_DRAIN_FILE_PATH) -> None:
"""
Create the drain file, then sleep. Runs as the worker pod's preStop hook,
which must finish before Kubernetes sends SIGTERM.
"""
Path(path).touch()
time.sleep(seconds)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this need to sleep? Can't it just exit immediately after writing the file?

@oioki oioki Oct 8, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an equivalent of the old touch /tmp/taskworker-draining && sleep 15. There is no sleep (because of no shell) outside of the subcommand, so we have to sleep here.

Initially that 15 sec sleep was added in https://github.com/getsentry/ops/pull/23208

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah right OK makes sense.



def main(argv: list[str] | None = None) -> None:
parser = argparse.ArgumentParser(
prog="python3 -m taskbroker_client.drain",
description="Create the worker drain file, then sleep.",
)
parser.add_argument("seconds", type=float, help="how long to sleep after creating the file")
args = parser.parse_args(argv)
drain(args.seconds)


if __name__ == "__main__":
main()
21 changes: 21 additions & 0 deletions clients/python/tests/test_drain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from pathlib import Path
from unittest import mock

from taskbroker_client.drain import drain, main


def test_drain_creates_file_before_sleeping(tmp_path: Path) -> None:
path = tmp_path / "draining"

def sleep(seconds: float) -> None:
assert path.exists()

with mock.patch("taskbroker_client.drain.time.sleep", side_effect=sleep) as sleep_mock:
drain(15, str(path))
sleep_mock.assert_called_once_with(15)


def test_main_parses_seconds() -> None:
with mock.patch("taskbroker_client.drain.drain") as drain_mock:
main(["15"])
drain_mock.assert_called_once_with(15.0)
Loading