import { statfs } from 'node:fs/promises' import logger from '@adonisjs/core/services/logger' /** How often free space is measured. */ const CHECK_MS = 60_000 /** Resumed only this much above the floor: not paused and resumed at every flush. */ const MARGIN_GB = 1 /** * Free space on the filesystem holding `path`, against a floor: low below it, again fine MARGIN_GB above it. In a * container `/` is an overlay on the host's Docker root, which on homelab is the NVMe the catalog and the WAL are on. * The prober filled it ~0.8–1.1 GB an hour at ~200 articles/s, and nothing stopped it at the 10 GB floor (LOG.md * 2026-10-18 (77)). Off when the floor is 0. */ export class DiskSpace { private checkedAt = 0 private low = false constructor( private what: string, private path: string, private floorGb: number, private free: (path: string) => Promise = async (p) => { const s = await statfs(p) return s.bavail * s.bsize }, private checkMs = CHECK_MS ) {} async short(): Promise { if (!this.floorGb) return false if (Date.now() - this.checkedAt < this.checkMs) return this.low this.checkedAt = Date.now() const gb = (await this.free(this.path)) / 1e9 const was = this.low this.low = gb < this.floorGb + (was ? MARGIN_GB : 0) if (this.low !== was) logger.info(`${gb.toFixed(1)} GB free (floor ${this.floorGb} GB): ${this.what} ${this.low ? 'paused' : 'resumed'}.`) return this.low } }