This commit is contained in:
team3
2026-10-05 22:09:06 +02:00
parent 16630f0368
commit f3ef3861a9
5 changed files with 18 additions and 23 deletions

View File

@@ -1,8 +1,7 @@
// Dateiabgleich für ~/.claude/projects (Claude-Code-Sitzungen und Memory), nur zwischen PCs.
// Reine Logik ohne Dateisystem, damit sie sich testen lässt. sync.js liest und schreibt die Dateien.
//
// Regeln: Eine Datei geht hoch, wenn sie sich geändert hat und seit einer Minute nicht angefasst wurde.
// Sitzungen wachsen nur am Ende, deshalb geht meist nur der neue Rest ("append"), zusammen mit dem
// Regeln: Eine Datei geht hoch, sobald sie sich geändert hat. Sitzungen wachsen nur am Ende, deshalb geht meist nur der neue Rest ("append"), zusammen mit dem
// Stand, den der Server haben müsste (base: Größe und Hash der letzten 64 KB). Vom Server kommt eine
// Datei, wenn sie dort neuer ist, ebenfalls nur ab dem eigenen Stand. Bei Konflikten gewinnt die neuere
// Änderungszeit. Verschwundene Dateien werden als Tombstone gemeldet, gelöschte vom Server lokal entfernt.

View File

@@ -23,11 +23,10 @@ const INTERVALS = [
// Kurze Wartezeit nach einer eigenen Änderung, damit mehrere Klicks in einem Lauf landen
const SOON_MS = 500;
// Dateien (Claude-Sitzungen und Memory): gleicher Takt wie die Einträge, hoch geht, was eine Minute ruht.
// Meist nur der neue Rest einer Datei, siehe files.js.
// Dateien (Claude-Sitzungen und Memory): gleicher Takt wie die Einträge, jede Änderung geht beim
// nächsten Lauf hoch, meist nur der neue Rest einer Datei, siehe files.js.
// "files" in sync.json: false schaltet ab, ein Pfad ersetzt ~/.claude/projects.
const FILES_FIRST_SECONDS = 10;
const FILES_IDLE_SECONDS = 60;
const FILES_BATCH_BYTES = 16 * 1024 * 1024;
// Von außen anstoßbar: make sync-files ruft diese Methode über D-Bus auf
@@ -84,15 +83,14 @@ export class Sync {
this._dbus.export(Gio.DBus.session, '/de/marha/desktop');
}
// Dateiabgleich sofort und erzwungen: auch Dateien, die noch keine Stunde ruhen.
// Die Antwort kommt erst, wenn er durch ist.
// Dateiabgleich sofort, die Antwort kommt erst, wenn er durch ist.
SyncFilesAsync(_params, invocation) {
const reply = text => invocation.return_value(new GLib.Variant('(s)', [text]));
if (!this._filesRoot) {
reply('Dateiabgleich ist aus ("files": false in sync.json)');
return;
}
this._filesCycle(true)
this._filesCycle()
.then(r => reply(r ? `hoch ${r.uploaded}, gelöscht gemeldet ${r.removed}, runter ${r.written}, lokal gelöscht ${r.deleted}` : 'läuft gerade schon'))
.catch(e => reply(`Fehler: ${e.message}`));
}
@@ -284,8 +282,7 @@ export class Sync {
// Eigener Lauf mit eigenem Stand: die Antwort enthält nur Dateien, der Takt der Einträge bleibt unberührt.
// Gibt zurück, was übertragen wurde, oder null, wenn gerade ein Lauf aktiv ist.
// force: Ruhezeit ignorieren, alles Geänderte geht hoch.
async _filesCycle(force = false) {
async _filesCycle() {
if (this._filesBusy || !this._filesRoot)
return null;
this._filesBusy = true;
@@ -294,7 +291,7 @@ export class Sync {
const state = this._state.files;
const local = scanFiles(this._filesRoot);
const now = Math.floor(GLib.get_real_time() / 1e6);
const {upload, remove} = planPush(local, state.pushed, now, force ? 0 : FILES_IDLE_SECONDS);
const {upload, remove} = planPush(local, state.pushed, now, 0);
const items = [];
for (const {id, updated} of upload) {
const bytes = readBytes(this._path(id));
@@ -368,7 +365,7 @@ export class Sync {
if (bytes)
state.pushed[file.id] = {updated: mine, size: bytes.length, hash: tailHash(bytes)};
}
// Sonst ist die lokale Datei neuer und geht hoch, sobald sie eine Minute ruht.
// Sonst ist die lokale Datei neuer und geht beim nächsten Lauf hoch.
}
state.cursor = response.cursor;
}