Files
Aether/backend/internal/documents/diskspace.go
T
HoneyandClaude Opus 5 31a027c93a feat(aether): initial commit – self-hosted Cloud, Phasen 1–7
Go-Backend (chi, pgx, golang-migrate) + React/TS-Frontend als PWA.
Enthalten: Auth inkl. OIDC, Dateien mit Versionen und Papierkorb,
Freigaben (Links + intern), WebDAV, Gruppenordner, Admin/Theming,
Volltextsuche mit OCR, eigener PDF-Betrachter und WOPI-Office
(Collabora/OnlyOffice).

Nicht im Repo: deploy/.env (Sitzungsschlüssel, DB- und Admin-Passwort)
sowie alle Daten- und Build-Verzeichnisse – siehe .gitignore.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 09:25:36 +02:00

67 lines
2.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package documents
import (
"fmt"
"os"
"path/filepath"
"strings"
"syscall"
)
// minFreeBytes ist die Untergrenze, unter der die Texterkennung pausiert.
//
// OCR ist das einzige Stück dieser Anwendung, das von sich aus und ohne
// Zutun eines Menschen Platz verbraucht: Es arbeitet eine Warteschlange ab,
// solange etwas darin liegt. Eine Cloud, die ihre eigene Platte vollschreibt,
// nimmt Uploads nicht mehr an – und das wäre dann kein OCR-Problem mehr,
// sondern ein Ausfall.
//
// 2 GiB ist mit Absicht großzügig: Der Sidecar einer Erkennung ist kaum größer
// als ein Megabyte, tesseract und ghostscript brauchen währenddessen aber
// Arbeitsdateien, deren Größe von der Auflösung der Vorlage abhängt. Lieber
// eine Weile nichts erkennen als eine volle Platte.
const minFreeBytes = 2 << 30 // 2 GiB
// freeBytes meldet den freien Platz auf dem Dateisystem, auf dem path liegt.
func freeBytes(path string) (uint64, error) {
var st syscall.Statfs_t
if err := syscall.Statfs(path, &st); err != nil {
return 0, fmt.Errorf("statfs %s: %w", path, err)
}
// Bavail, nicht Bfree: Bfree zählt auch die Reserve mit, die nur root
// benutzen darf – der Server läuft aber als unprivilegierter Nutzer und
// käme daran nie heran.
return st.Bavail * uint64(st.Bsize), nil
}
// sweepTemp räumt Zwischendateien früherer Läufe weg.
//
// Im Normalfall räumt der Arbeiter selbst auf. Wird der Container aber hart
// beendet – `docker kill`, ein Absturz, Stromausfall –, läuft kein defer mehr,
// und die angefangene Datei bleibt liegen. Ohne diesen Durchgang sammelt sich
// das über Monate an, ausgerechnet auf der Platte, die auch die Dateien trägt.
//
// Es wird nur weggeräumt, was diese Anwendung selbst angelegt hat: das Präfix
// "ocr-" im Zwischenverzeichnis. Fremde Dateien bleiben unangetastet.
func sweepTemp(dir string) (int, int64) {
entries, err := os.ReadDir(dir)
if err != nil {
return 0, 0
}
var count int
var bytes int64
for _, e := range entries {
if e.IsDir() || !strings.HasPrefix(e.Name(), "ocr-") {
continue
}
full := filepath.Join(dir, e.Name())
if info, err := e.Info(); err == nil {
bytes += info.Size()
}
if err := os.Remove(full); err == nil {
count++
}
}
return count, bytes
}