Serial/parallel transfers setting
Transfers: Single | Multi in the options popover, with an 'At once' picker (2/3/4/6/8) when Multi. Engine concurrency becomes an instance field applied live: at boot from settings.json and on every saveSettings (raising the limit starts queued jobs immediately). Verified headless: 3 slow jobs overlap at concurrency 3, stay strictly serial at 1, clamp works. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { BrowserWindow, Updater } from "electrobun/bun";
|
||||
import { BRANDING } from "../shared/branding";
|
||||
import { effectiveConcurrency } from "../shared/types";
|
||||
import { SessionRegistry } from "./fs/registry";
|
||||
import { createAppRPC } from "./rpc-handlers";
|
||||
import { ConnectionStore } from "./store/connections";
|
||||
@@ -58,5 +59,6 @@ new BrowserWindow({
|
||||
|
||||
engine.onUpdate = (snapshot) => rpc.send.transferUpdate(snapshot);
|
||||
events.sessionClosed = (info) => rpc.send.sessionClosed(info);
|
||||
void settings.load().then((s) => engine.setConcurrency(effectiveConcurrency(s)));
|
||||
|
||||
console.log(`${BRANDING.appName} started (${url})`);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { BrowserView } from "electrobun/bun";
|
||||
import type { AppRPC } from "../shared/rpc";
|
||||
import type { Result } from "../shared/types";
|
||||
import { effectiveConcurrency, type Result } from "../shared/types";
|
||||
import type { SessionRegistry } from "./fs/registry";
|
||||
import { SftpProvider } from "./fs/sftp";
|
||||
import type { ConnectionStore } from "./store/connections";
|
||||
@@ -144,6 +144,7 @@ export function createAppRPC({ registry, engine, store, settings, events }: AppD
|
||||
saveSettings: ({ settings: next }) =>
|
||||
wrap(async () => {
|
||||
await settings.save(next);
|
||||
engine.setConcurrency(effectiveConcurrency(next));
|
||||
return {};
|
||||
}),
|
||||
},
|
||||
|
||||
@@ -5,8 +5,6 @@ import type { FileSystemProvider } from "../fs/provider";
|
||||
import type { SessionRegistry } from "../fs/registry";
|
||||
import { walkTree } from "./walk";
|
||||
|
||||
// One at a time keeps remote servers happy; bump for parallel jobs.
|
||||
const TRANSFER_CONCURRENCY = 1;
|
||||
const PROGRESS_INTERVAL_MS = 100;
|
||||
|
||||
interface Job {
|
||||
@@ -41,9 +39,16 @@ export class TransferEngine {
|
||||
private running = 0;
|
||||
private counter = 0;
|
||||
private lastEmit = new Map<string, number>();
|
||||
// serial by default; the transfers setting raises it (jobs are independent)
|
||||
private concurrency = 1;
|
||||
|
||||
constructor(private registry: SessionRegistry) {}
|
||||
|
||||
setConcurrency(n: number): void {
|
||||
this.concurrency = Math.max(1, Math.min(8, Math.round(n) || 1));
|
||||
this.pump(); // a raised limit starts queued jobs immediately
|
||||
}
|
||||
|
||||
enqueue(params: {
|
||||
srcSessionId: string;
|
||||
items: { path: string; type: EntryType }[];
|
||||
@@ -119,7 +124,7 @@ export class TransferEngine {
|
||||
}
|
||||
|
||||
private pump(): void {
|
||||
while (this.running < TRANSFER_CONCURRENCY && this.queue.length) {
|
||||
while (this.running < this.concurrency && this.queue.length) {
|
||||
const job = this.queue.shift()!;
|
||||
this.running++;
|
||||
this.run(job)
|
||||
|
||||
Reference in New Issue
Block a user