This commit is contained in:
team3
2026-09-22 13:39:16 +02:00
parent acfe29dae7
commit 23d4b08d4f
7 changed files with 78 additions and 13 deletions

View File

@@ -56,6 +56,8 @@ export class Sync {
this._filesTimerId = null;
this._filesBusy = false;
this._session = new Soup.Session({timeout: 10});
// Dateien sind groß, der Server braucht für ein Paket länger als für Einträge
this._filesSession = new Soup.Session({timeout: 120});
this._busy = false;
this._failing = false;
this._timerId = null;
@@ -148,6 +150,7 @@ export class Sync {
// Laufende Anfrage abbrechen, ohne das als Verbindungsfehler zu melden
this._stopped = true;
this._session.abort();
this._filesSession.abort();
}
async _cycle() {
@@ -195,12 +198,12 @@ export class Sync {
};
}
_post(payload) {
_post(payload, session = this._session) {
const message = Soup.Message.new('POST', `${this._config.url}/api/sync`);
message.request_headers.append('Authorization', `Bearer ${this._config.token}`);
message.set_request_body_from_bytes('application/json', new GLib.Bytes(new TextEncoder().encode(JSON.stringify(payload))));
return new Promise((resolve, reject) => {
this._session.send_and_read_async(message, GLib.PRIORITY_DEFAULT, null, (session, result) => {
session.send_and_read_async(message, GLib.PRIORITY_DEFAULT, null, (session, result) => {
try {
const bytes = session.send_and_read_finish(result);
if (message.get_status() !== Soup.Status.OK)
@@ -294,13 +297,18 @@ export class Sync {
const nowStamp = new Date(now * 1000).toISOString();
for (const id of remove)
items.push({id, updated: nowStamp, deleted: true});
// Mindestens ein Lauf, auch ohne eigene Änderungen: holt Neues vom Server
const packets = items.length ? batches(items, item => (item.content ?? '').length, FILES_BATCH_BYTES) : [[]];
for (const files of packets) {
const response = await this._post({since: state.cursor, files});
// Hoch in Paketen, runter in Paketen: solange der Server "more" meldet, weiter fragen
const packets = batches(items, item => (item.content ?? '').length, FILES_BATCH_BYTES);
let index = 0;
let more = true;
while (index < packets.length || more) {
const files = packets[index++] ?? [];
const before = state.cursor;
const response = await this._post({since: state.cursor, files}, this._filesSession);
// Ein Server ohne Dateien-Sammlung würde alles verwerfen, der Stand bliebe sonst falsch
if (!Array.isArray(response.files))
throw new Error('Server kennt keine Dateien, dort erst make prod ausführen');
more = Boolean(response.more) && response.cursor !== before;
for (const item of files) {
state.pushed[item.id] = item.deleted ? null : item.updated;
result[item.deleted ? 'removed' : 'uploaded']++;