feat: upload progress display, semaphore fix, context menu polish
- Status bar shows uploaded/total bytes (e.g. "16 GB / 281 GB") Total is sum of all queue jobs (100GB x 4 hosters = 400GB) - Fix semaphore acquisition order: hoster-first then global prevents jobs waiting on a hoster slot from wasting global semaphore slots, significantly increasing active connection utilization - Context menu: dynamic count on all labels, singular/plural for single selection, user-adjusted grouping with separators Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d955403c7a
commit
399e2fbe70
@ -239,14 +239,16 @@ class UploadManager extends EventEmitter {
|
|||||||
maxAttempts
|
maxAttempts
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Acquire hoster semaphore first so jobs waiting for a hoster slot
|
||||||
|
// don't waste global slots (prevents underutilization)
|
||||||
|
await hosterSemaphore.acquire(signal);
|
||||||
|
hosterSlotAcquired = true;
|
||||||
|
|
||||||
if (globalSemaphore) {
|
if (globalSemaphore) {
|
||||||
await globalSemaphore.acquire(signal);
|
await globalSemaphore.acquire(signal);
|
||||||
globalSlotAcquired = true;
|
globalSlotAcquired = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
await hosterSemaphore.acquire(signal);
|
|
||||||
hosterSlotAcquired = true;
|
|
||||||
|
|
||||||
if (settings.timeIntervalSec > 0) {
|
if (settings.timeIntervalSec > 0) {
|
||||||
await this._waitForInterval(task.hoster, settings.timeIntervalSec * 1000, signal);
|
await this._waitForInterval(task.hoster, settings.timeIntervalSec * 1000, signal);
|
||||||
}
|
}
|
||||||
@ -438,8 +440,9 @@ class UploadManager extends EventEmitter {
|
|||||||
this.activeJobs.delete(uploadId);
|
this.activeJobs.delete(uploadId);
|
||||||
this.jobAbortControllers.delete(jobId);
|
this.jobAbortControllers.delete(jobId);
|
||||||
cleanupSignals();
|
cleanupSignals();
|
||||||
if (hosterSlotAcquired) hosterSemaphore.release();
|
// Release in reverse order of acquire (global first, then hoster)
|
||||||
if (globalSlotAcquired && globalSemaphore) globalSemaphore.release();
|
if (globalSlotAcquired && globalSemaphore) globalSemaphore.release();
|
||||||
|
if (hosterSlotAcquired) hosterSemaphore.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1465,7 +1465,8 @@ function updateStatusBar() {
|
|||||||
|
|
||||||
document.getElementById('sbState').textContent = stateText;
|
document.getElementById('sbState').textContent = stateText;
|
||||||
document.getElementById('sbSpeed').textContent = formatSpeed(lastUploadStats.globalSpeedKbs || 0);
|
document.getElementById('sbSpeed').textContent = formatSpeed(lastUploadStats.globalSpeedKbs || 0);
|
||||||
document.getElementById('sbTotal').textContent = formatSize(lastUploadStats.totalBytes || 0);
|
const queueTotalBytes = queueJobs.reduce((sum, j) => sum + (j.bytesTotal || 0), 0);
|
||||||
|
document.getElementById('sbTotal').textContent = `${formatSize(lastUploadStats.totalBytes || 0)} / ${formatSize(queueTotalBytes)}`;
|
||||||
document.getElementById('sbEta').textContent = `ETA ${etaSeconds > 0 ? formatTime(etaSeconds) : '--:--'}`;
|
document.getElementById('sbEta').textContent = `ETA ${etaSeconds > 0 ? formatTime(etaSeconds) : '--:--'}`;
|
||||||
document.getElementById('sbConnections').textContent = `Aktive Verbindungen ${lastUploadStats.activeJobs || 0}`;
|
document.getElementById('sbConnections').textContent = `Aktive Verbindungen ${lastUploadStats.activeJobs || 0}`;
|
||||||
document.getElementById('sbQueueCount').textContent = `Gesamt ${counts.total}`;
|
document.getElementById('sbQueueCount').textContent = `Gesamt ${counts.total}`;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user