Optimize debug log I/O and settings auto-refresh polling (v4.1.11)
This commit is contained in:
parent
9392398db7
commit
8d656772fc
4
typescript-version/package-lock.json
generated
4
typescript-version/package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "twitch-vod-manager",
|
"name": "twitch-vod-manager",
|
||||||
"version": "4.1.10",
|
"version": "4.1.11",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "twitch-vod-manager",
|
"name": "twitch-vod-manager",
|
||||||
"version": "4.1.10",
|
"version": "4.1.11",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.6.0",
|
"axios": "^1.6.0",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "twitch-vod-manager",
|
"name": "twitch-vod-manager",
|
||||||
"version": "4.1.10",
|
"version": "4.1.11",
|
||||||
"description": "Twitch VOD Manager - Download Twitch VODs easily",
|
"description": "Twitch VOD Manager - Download Twitch VODs easily",
|
||||||
"main": "dist/main.js",
|
"main": "dist/main.js",
|
||||||
"author": "xRangerDE",
|
"author": "xRangerDE",
|
||||||
|
|||||||
@ -457,7 +457,7 @@
|
|||||||
|
|
||||||
<div class="settings-card">
|
<div class="settings-card">
|
||||||
<h3 id="updateTitle">Updates</h3>
|
<h3 id="updateTitle">Updates</h3>
|
||||||
<p id="versionInfo" style="margin-bottom: 10px; color: var(--text-secondary);">Version: v4.1.10</p>
|
<p id="versionInfo" style="margin-bottom: 10px; color: var(--text-secondary);">Version: v4.1.11</p>
|
||||||
<button class="btn-secondary" id="checkUpdateBtn" onclick="checkUpdate()">Nach Updates suchen</button>
|
<button class="btn-secondary" id="checkUpdateBtn" onclick="checkUpdate()">Nach Updates suchen</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -502,7 +502,7 @@
|
|||||||
<div class="status-dot" id="statusDot"></div>
|
<div class="status-dot" id="statusDot"></div>
|
||||||
<span id="statusText">Nicht verbunden</span>
|
<span id="statusText">Nicht verbunden</span>
|
||||||
</div>
|
</div>
|
||||||
<span id="versionText">v4.1.10</span>
|
<span id="versionText">v4.1.11</span>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import { autoUpdater } from 'electron-updater';
|
|||||||
// ==========================================
|
// ==========================================
|
||||||
// CONFIG & CONSTANTS
|
// CONFIG & CONSTANTS
|
||||||
// ==========================================
|
// ==========================================
|
||||||
const APP_VERSION = '4.1.10';
|
const APP_VERSION = '4.1.11';
|
||||||
const UPDATE_CHECK_URL = 'http://24-music.de/version.json';
|
const UPDATE_CHECK_URL = 'http://24-music.de/version.json';
|
||||||
|
|
||||||
// Paths
|
// Paths
|
||||||
@ -30,6 +30,9 @@ const MIN_FREE_DISK_BYTES = 128 * 1024 * 1024;
|
|||||||
const TOOL_PATH_REFRESH_TTL_MS = 10 * 1000;
|
const TOOL_PATH_REFRESH_TTL_MS = 10 * 1000;
|
||||||
const DEBUG_LOG_FLUSH_INTERVAL_MS = 1000;
|
const DEBUG_LOG_FLUSH_INTERVAL_MS = 1000;
|
||||||
const DEBUG_LOG_BUFFER_FLUSH_LINES = 48;
|
const DEBUG_LOG_BUFFER_FLUSH_LINES = 48;
|
||||||
|
const DEBUG_LOG_READ_TAIL_BYTES = 512 * 1024;
|
||||||
|
const DEBUG_LOG_MAX_BYTES = 8 * 1024 * 1024;
|
||||||
|
const DEBUG_LOG_TRIM_TO_BYTES = 4 * 1024 * 1024;
|
||||||
const AUTO_UPDATE_CHECK_INTERVAL_MS = 10 * 60 * 1000;
|
const AUTO_UPDATE_CHECK_INTERVAL_MS = 10 * 60 * 1000;
|
||||||
const AUTO_UPDATE_STARTUP_CHECK_DELAY_MS = 5000;
|
const AUTO_UPDATE_STARTUP_CHECK_DELAY_MS = 5000;
|
||||||
const AUTO_UPDATE_MIN_CHECK_GAP_MS = 45 * 1000;
|
const AUTO_UPDATE_MIN_CHECK_GAP_MS = 45 * 1000;
|
||||||
@ -533,11 +536,78 @@ function flushPendingDebugLogLines(): void {
|
|||||||
const payload = pendingDebugLogLines.join('');
|
const payload = pendingDebugLogLines.join('');
|
||||||
pendingDebugLogLines = [];
|
pendingDebugLogLines = [];
|
||||||
fs.appendFileSync(DEBUG_LOG_FILE, payload);
|
fs.appendFileSync(DEBUG_LOG_FILE, payload);
|
||||||
|
trimDebugLogFileIfNeeded();
|
||||||
} catch {
|
} catch {
|
||||||
// ignore debug log errors
|
// ignore debug log errors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function trimDebugLogFileIfNeeded(): void {
|
||||||
|
try {
|
||||||
|
if (!fs.existsSync(DEBUG_LOG_FILE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const stats = fs.statSync(DEBUG_LOG_FILE);
|
||||||
|
if (stats.size <= DEBUG_LOG_MAX_BYTES) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bytesToKeep = Math.min(DEBUG_LOG_TRIM_TO_BYTES, stats.size);
|
||||||
|
const startOffset = Math.max(0, stats.size - bytesToKeep);
|
||||||
|
const buffer = Buffer.allocUnsafe(bytesToKeep);
|
||||||
|
|
||||||
|
let fileHandle: number | null = null;
|
||||||
|
try {
|
||||||
|
fileHandle = fs.openSync(DEBUG_LOG_FILE, 'r');
|
||||||
|
fs.readSync(fileHandle, buffer, 0, bytesToKeep, startOffset);
|
||||||
|
} finally {
|
||||||
|
if (fileHandle !== null) {
|
||||||
|
fs.closeSync(fileHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstLineBreak = buffer.indexOf(0x0a);
|
||||||
|
const trimmed = firstLineBreak >= 0 && firstLineBreak + 1 < buffer.length
|
||||||
|
? buffer.subarray(firstLineBreak + 1)
|
||||||
|
: buffer;
|
||||||
|
|
||||||
|
fs.writeFileSync(DEBUG_LOG_FILE, trimmed);
|
||||||
|
} catch {
|
||||||
|
// ignore debug log errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function readDebugLogTailFromDisk(): string {
|
||||||
|
const stats = fs.statSync(DEBUG_LOG_FILE);
|
||||||
|
if (stats.size <= 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const bytesToRead = Math.min(stats.size, DEBUG_LOG_READ_TAIL_BYTES);
|
||||||
|
if (bytesToRead === stats.size) {
|
||||||
|
return fs.readFileSync(DEBUG_LOG_FILE, 'utf-8');
|
||||||
|
}
|
||||||
|
|
||||||
|
const buffer = Buffer.allocUnsafe(bytesToRead);
|
||||||
|
let fileHandle: number | null = null;
|
||||||
|
try {
|
||||||
|
fileHandle = fs.openSync(DEBUG_LOG_FILE, 'r');
|
||||||
|
fs.readSync(fileHandle, buffer, 0, bytesToRead, stats.size - bytesToRead);
|
||||||
|
} finally {
|
||||||
|
if (fileHandle !== null) {
|
||||||
|
fs.closeSync(fileHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstLineBreak = buffer.indexOf(0x0a);
|
||||||
|
const slice = firstLineBreak >= 0 && firstLineBreak + 1 < buffer.length
|
||||||
|
? buffer.subarray(firstLineBreak + 1)
|
||||||
|
: buffer;
|
||||||
|
|
||||||
|
return slice.toString('utf-8');
|
||||||
|
}
|
||||||
|
|
||||||
function startDebugLogFlushTimer(): void {
|
function startDebugLogFlushTimer(): void {
|
||||||
if (debugLogFlushTimer) {
|
if (debugLogFlushTimer) {
|
||||||
return;
|
return;
|
||||||
@ -569,7 +639,7 @@ function readDebugLog(lines = 200): string {
|
|||||||
return 'Debug-Log ist leer.';
|
return 'Debug-Log ist leer.';
|
||||||
}
|
}
|
||||||
|
|
||||||
const text = fs.readFileSync(DEBUG_LOG_FILE, 'utf-8');
|
const text = readDebugLogTailFromDisk();
|
||||||
const rows = text.split(/\r?\n/).filter(Boolean);
|
const rows = text.split(/\r?\n/).filter(Boolean);
|
||||||
return rows.slice(-lines).join('\n') || 'Debug-Log ist leer.';
|
return rows.slice(-lines).join('\n') || 'Debug-Log ist leer.';
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@ -1,4 +1,13 @@
|
|||||||
let lastRuntimeMetricsOutput = '';
|
let lastRuntimeMetricsOutput = '';
|
||||||
|
let lastDebugLogOutput = '';
|
||||||
|
|
||||||
|
function canRunSettingsAutoRefresh(): boolean {
|
||||||
|
if (document.hidden) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return document.querySelector('.tab-content.active')?.id === 'settingsTab';
|
||||||
|
}
|
||||||
|
|
||||||
async function connect(): Promise<void> {
|
async function connect(): Promise<void> {
|
||||||
const hasCredentials = Boolean((config.client_id ?? '').toString().trim() && (config.client_secret ?? '').toString().trim());
|
const hasCredentials = Boolean((config.client_id ?? '').toString().trim() && (config.client_secret ?? '').toString().trim());
|
||||||
@ -142,6 +151,10 @@ function toggleRuntimeMetricsAutoRefresh(enabled: boolean): void {
|
|||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
runtimeMetricsAutoRefreshTimer = window.setInterval(() => {
|
runtimeMetricsAutoRefreshTimer = window.setInterval(() => {
|
||||||
|
if (!canRunSettingsAutoRefresh()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void refreshRuntimeMetrics(false);
|
void refreshRuntimeMetrics(false);
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
@ -245,9 +258,17 @@ async function runPreflight(autoFix = false): Promise<void> {
|
|||||||
async function refreshDebugLog(): Promise<void> {
|
async function refreshDebugLog(): Promise<void> {
|
||||||
const text = await window.api.getDebugLog(250);
|
const text = await window.api.getDebugLog(250);
|
||||||
const panel = byId('debugLogOutput');
|
const panel = byId('debugLogOutput');
|
||||||
|
const keepAtBottom = (panel.scrollHeight - panel.scrollTop - panel.clientHeight) < 20;
|
||||||
|
|
||||||
|
if (text !== lastDebugLogOutput) {
|
||||||
panel.textContent = text;
|
panel.textContent = text;
|
||||||
|
lastDebugLogOutput = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keepAtBottom) {
|
||||||
panel.scrollTop = panel.scrollHeight;
|
panel.scrollTop = panel.scrollHeight;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function toggleDebugAutoRefresh(enabled: boolean): void {
|
function toggleDebugAutoRefresh(enabled: boolean): void {
|
||||||
if (debugLogAutoRefreshTimer) {
|
if (debugLogAutoRefreshTimer) {
|
||||||
@ -257,8 +278,12 @@ function toggleDebugAutoRefresh(enabled: boolean): void {
|
|||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
debugLogAutoRefreshTimer = window.setInterval(() => {
|
debugLogAutoRefreshTimer = window.setInterval(() => {
|
||||||
|
if (!canRunSettingsAutoRefresh()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void refreshDebugLog();
|
void refreshDebugLog();
|
||||||
}, 1500);
|
}, 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user