update
This commit is contained in:
@@ -28,6 +28,8 @@ const SOON_MS = 500;
|
||||
// "files" in sync.json: false schaltet ab, ein Pfad ersetzt ~/.claude/projects.
|
||||
const FILES_FIRST_SECONDS = 10;
|
||||
const FILES_BATCH_BYTES = 16 * 1024 * 1024;
|
||||
// So lange über das Soup-Timeout hinaus warten wir auf eine Antwort, siehe request()
|
||||
const REQUEST_GRACE_SECONDS = 10;
|
||||
|
||||
// Von außen anstoßbar: make sync-files ruft diese Methode über D-Bus auf
|
||||
const DBUS_IFACE = `
|
||||
@@ -201,18 +203,7 @@ export class Sync {
|
||||
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) => {
|
||||
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)
|
||||
throw new Error(`HTTP ${message.get_status()} ${message.get_reason_phrase()}`);
|
||||
resolve(JSON.parse(new TextDecoder().decode(bytes.get_data())));
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
return request(session, message, bytes => JSON.parse(new TextDecoder().decode(bytes.get_data())));
|
||||
}
|
||||
|
||||
// Antwort einarbeiten. Was der Server zurückschickt und wir gerade hochgeladen haben, kennt er jetzt.
|
||||
@@ -375,18 +366,10 @@ export class Sync {
|
||||
const path = id.split('/').map(encodeURIComponent).join('/');
|
||||
const message = Soup.Message.new('GET', `${this._config.url}/api/files/${path}?from=${from}&hash=${hash}`);
|
||||
message.request_headers.append('Authorization', `Bearer ${this._config.token}`);
|
||||
return new Promise((resolve, reject) => {
|
||||
this._filesSession.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)
|
||||
throw new Error(`HTTP ${message.get_status()} ${message.get_reason_phrase()}`);
|
||||
resolve({bytes: bytes.get_data() ?? new Uint8Array(0), from: Number(message.get_response_headers().get_one('X-From'))});
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
return request(this._filesSession, message, bytes => ({
|
||||
bytes: bytes.get_data() ?? new Uint8Array(0),
|
||||
from: Number(message.get_response_headers().get_one('X-From')),
|
||||
}));
|
||||
}
|
||||
|
||||
_fail(message) {
|
||||
@@ -423,6 +406,33 @@ function scanFiles(root) {
|
||||
return local;
|
||||
}
|
||||
|
||||
// Anfrage schicken und die Antwort lesen. GJS verwirft den Soup-Callback gelegentlich, wenn er
|
||||
// während der Garbage Collection fällig wird. Dann käme nie eine Antwort, der Lauf bliebe für immer
|
||||
// "beschäftigt" und der Takt stünde still. Deshalb eine eigene Frist über dem Soup-Timeout:
|
||||
// danach gilt die Anfrage als gescheitert, der nächste Lauf kommt wie geplant.
|
||||
function request(session, message, read) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let watchdog = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, session.timeout + REQUEST_GRACE_SECONDS, () => {
|
||||
watchdog = null;
|
||||
reject(new Error('keine Antwort, Anfrage verworfen'));
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
session.send_and_read_async(message, GLib.PRIORITY_DEFAULT, null, (_session, result) => {
|
||||
if (watchdog)
|
||||
GLib.source_remove(watchdog);
|
||||
watchdog = null;
|
||||
try {
|
||||
const bytes = session.send_and_read_finish(result);
|
||||
if (message.get_status() !== Soup.Status.OK)
|
||||
throw new Error(`HTTP ${message.get_status()} ${message.get_reason_phrase()}`);
|
||||
resolve(read(bytes));
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Datei als Bytes lesen. null, wenn sie fehlt.
|
||||
function readBytes(path) {
|
||||
try {
|
||||
@@ -434,6 +444,8 @@ function readBytes(path) {
|
||||
}
|
||||
|
||||
function appendBytes(path, bytes) {
|
||||
if (!bytes.length)
|
||||
return;
|
||||
const stream = Gio.File.new_for_path(path).append_to(Gio.FileCreateFlags.NONE, null);
|
||||
stream.write_bytes(new GLib.Bytes(bytes), null);
|
||||
stream.close(null);
|
||||
|
||||
Reference in New Issue
Block a user