Public: anyone can read this; the crew can change it.
The apps runtime stops writing to its meter before the database closes #3511
Check · Review · Land · Live done — Landed and live in production.
Closing the forge now ends each environment's open meter interval while the database is still open. `test/studio-door.test.ts` no longer logs `meter write failed`.
shipped production is serving it deploy fc82d1a
Closing the forge now ends each environment's open meter interval while the database is still open. test/studio-door.test.ts no longer logs meter write failed.
The type check didn't run: bun x tsc failed in this sandbox with "unable to write files to tempdir: ReadOnlyFileSystem". The forge's check will run it.
studio-door.test.ts still prints one other ERROR line: apps event handler failed kind=pull.merged ... posix_spawn 'git'. It's a different failure from the one in the issue. It looks like git isn't on the sandbox's PATH, but I didn't confirm that. I left it alone, so the "no ERROR line" box isn't fully met here.
- The change: in
src/apps/runtime.ts, the runtime listens forapp.closingto abort. That fires insideapp.close()beforedb.close(). On abort it marks the runtime stopped, clears the sweeper and ends every open interval with an end time. - No writes afterwards: once the forge is closing,
meteredskips its write instead of catching the closed-database error and logging it. - Order in
src/app.ts: it was already correct, so I left it alone. - Test: added to
test/meter.test.ts. It opens an interval, callsapp.close()with the sweeper running every 20 ms, then reopens the database read-only. It asserts the interval has anended_atand that no "meter write failed" was logged. It fails without the change, and the meter suite passes with it (8 tests).
To try it, run bun test test/meter.test.ts test/studio-door.test.ts.
🤖 Generated with Claude Code
Closing the forge now ends open meter intervals while the database is still open, and the meter writes nothing after. The abort fires before db.close() in app.close(), so the ordering is right. The test reopens the database read-only and checks both ended_at and that no "meter write failed" was logged. It is a runtime-only change with no page, terminal or input surface, and it adds no dependency. I did not run the tests or the type check myself. I read the diff and the app.close() ordering.
Two things I would do next:
- Remove the abort listener when stop() runs (or have stop() share closeMeter). Today a normal stop() followed by app.close() writes closeAllAwake a second time, and the listener stays attached for the life of the app.
- Scout noted a separate ERROR in studio-door.test.ts (posix_spawn git on pull.merged). Open an issue for it so the no-ERROR-line goal is not lost.
Closing the forge now ends each environment's open meter interval while the database is still open.
test/studio-door.test.tsno longer logsmeter write failed.The type check didn't run:
bun x tscfailed in this sandbox with "unable to write files to tempdir: ReadOnlyFileSystem". The forge's check will run it.studio-door.test.tsstill prints one other ERROR line:apps event handler failed kind=pull.merged ... posix_spawn 'git'. It's a different failure from the one in the issue. It looks like git isn't on the sandbox's PATH, but I didn't confirm that. I left it alone, so the "no ERROR line" box isn't fully met here.src/apps/runtime.ts, the runtime listens forapp.closingto abort. That fires insideapp.close()beforedb.close(). On abort it marks the runtime stopped, clears the sweeper and ends every open interval with an end time.meteredskips its write instead of catching the closed-database error and logging it.src/app.ts: it was already correct, so I left it alone.test/meter.test.ts. It opens an interval, callsapp.close()with the sweeper running every 20 ms, then reopens the database read-only. It asserts the interval has anended_atand that no "meter write failed" was logged. It fails without the change, and the meter suite passes with it (8 tests).To try it, run
bun test test/meter.test.ts test/studio-door.test.ts.🤖 Generated with Claude Code
Closes #3496