Stop the flow store leaking git zombies, honour VITE_API_URL from .env
`FlowStore._git` now passes `-c gc.auto=0`, so `git commit` no longer forks a background `gc --auto` that reparents onto PID 1 and stays there unreaped. With auto-gc off nothing packs on its own, so `_commit` runs a foreground `git gc` every 500 commits — the trigger a long-lived seeding session actually reaches. `docker/compose.yml` takes the frontend's `VITE_API_URL` build arg from the environment, keeping `https://api.${DOMAIN}` only as the fallback. `setup.sh` already derives the scheme from `ENVIRONMENT`, so an `up --build` that does not layer `compose.local.yml` stops shipping a bundle that calls `https://api.localhost`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01StpRc2C6au1WJ1EUU7fsfu
This commit is contained in:
@@ -97,6 +97,13 @@ class FlowStore:
|
||||
#: One warning per process when there is no git to commit with.
|
||||
_warned_no_git = False
|
||||
|
||||
#: Commits between housekeeping runs. Auto-gc is off (see `_git`), so
|
||||
#: nothing packs unless it is asked for; a commit counter is the trigger
|
||||
#: because the process that needs it never restarts — a seeding session
|
||||
#: commits thousands of times inside one long-lived container, which is how
|
||||
#: a store reached 1898 commits, 5863 loose objects and no pack at all.
|
||||
_GC_EVERY = 500
|
||||
|
||||
def __init__(self, root: Path) -> None:
|
||||
self.root = root
|
||||
self.root.mkdir(parents=True, exist_ok=True)
|
||||
@@ -120,7 +127,13 @@ class FlowStore:
|
||||
def _git(self, *args: str) -> subprocess.CompletedProcess[str]:
|
||||
try:
|
||||
return subprocess.run(
|
||||
["git", "-C", str(self.root), *args],
|
||||
# `gc.auto=0` on every invocation, because `git commit` otherwise
|
||||
# forks a background `gc --auto` and returns without waiting for
|
||||
# it. `subprocess.run` reaps the commit, not its grandchild, so
|
||||
# the daemon is reparented onto PID 1 — the FastAPI process,
|
||||
# which reaps nothing, and the zombies accumulate one per save.
|
||||
# Packing is asked for explicitly in `_commit` instead.
|
||||
["git", "-C", str(self.root), "-c", "gc.auto=0", *args],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False,
|
||||
@@ -158,6 +171,11 @@ class FlowStore:
|
||||
message,
|
||||
)
|
||||
if result.returncode == 0 or "nothing to commit" in result.stdout:
|
||||
if self.revision % self._GC_EVERY == 0:
|
||||
# In the foreground, so this child is waited on rather than
|
||||
# orphaned. Plain `gc` rather than `gc --auto`, which the flag
|
||||
# above has just disabled.
|
||||
self._git("gc", "--quiet")
|
||||
return
|
||||
if result.stderr == "git is not installed":
|
||||
# Already said once, in `_git`. Repeating it per save is noise.
|
||||
|
||||
Reference in New Issue
Block a user