Skip to content

Plain workspaces keep an unbounded recursive watcher alive after #1779 #2336

Description

@MateoCerquetella

Summary

bb-app 0.39.0 OOMed a Linux host because bb-parcel-watcher-child.mjs grew to about 11.4 GiB RSS while remaining responsive. PR #2041 substantially reduced the recursive tree by ignoring nested .git, node_modules, and caches, but current main still starts a recursive Parcel subscription for every non-Git workspace even though the only Git-status transition it needs to detect is <root>/.git appearing; the proxy also treats a pong as healthy regardless of RSS.

Expected: a plain workspace should detect git init without recursively indexing its entire tree, and a responsive native watcher should be recycled before it can OOM the whole service.

Versions and environment

  • Incident: bb-app 0.39.0 installed globally and managed by a systemd user service
  • Linux 6.18.42-1-cachyos-lts x86_64
  • Node v22.23.1
  • 25 GiB RAM and 25 GiB swap
  • Current-main inspection/repro: 494f66526913557ab076e048218236f0a6610927
  • Unmanaged non-Git environments included /home/dyaus and /home/dyaus/Developer, with several nested project environments

Steps to reproduce

  1. Register or open environment detail for an unmanaged non-Git workspace rooted at a broad directory such as a home or developer directory.
  2. Observe that WorkspaceStatusWatcher.startAsync() calls startWatchSubscription() for that root even though .git does not exist.
  3. Observe bb-parcel-watcher-child.mjs RSS while the environment remains subscribed. Pongs continue, so the proxy does not recycle it for memory growth.
  4. Unit-level current-main repro: assert that @parcel/watcher.subscribe is not called before git init; the assertion fails because one recursive subscription is installed immediately.

I did not intentionally reproduce the 11 GiB endpoint on current main; doing so risks another shared-host OOM. The structural plain-root subscription and absence of an RSS ceiling are both present at the commit above.

Expected vs actual

Actual incident output:

oom-kill:constraint=CONSTRAINT_NONE,...,task_memcg=/user.slice/user-1000.slice/user@1000.service/app.slice/bb-primary.service,task=node,pid=1044,uid=1000
Out of memory: Killed process 1044 (node) total-vm:33655680kB, anon-rss:11988468kB, file-rss:40160kB, shmem-rss:0kB
bb-primary.service: Failed with result 'oom-kill'.
bb-primary.service: Consumed 1h 59min 752ms CPU time over 11h 56min 28.490s wall clock time, 16.6G memory peak, 20.8G memory swap peak.

Current-main regression output:

AssertionError: expected [ [Function] ] to have a length of +0 but got 1

Expected: no recursive Parcel subscription while the workspace is non-Git; git init promotion still occurs promptly; a sustained high-RSS child cannot OOM the service.

Evidence

What you ruled out

Suggested priority and effort

High impact when triggered because the entire BB service is killed; workaround is to avoid broad non-Git environment roots. Estimated medium effort.

AGENT GENERATED

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions