Add cleanup procedure for unused Microbot clients#25
Conversation
- Implement getClientsJarTTL to manage clients jar TTL data - Add cleanupUnusedClientsJar to remove old jar files - Introduce updateClientJarTTL to update last used timestamps - Integrate IPC handlers for cleanup and update operations - Expose new functions in preload.js for renderer access - Update renderer.js to call new functions for jar management - Remove unused properties from defaultProperties in properties.js - Bump version in package.json to 3.2.3
WalkthroughAdds TTL tracking and cleanup for microbot client JARs: new functions in Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant UI as Renderer (UI)
participant Preload as Preload Bridge
participant IPC as Main IPC
participant Dir as dir-module
rect rgb(240,248,255)
note over UI,Dir: TTL refresh when launching a client
User->>UI: start client (with version)
UI->>Preload: updateClientJarTTL(version)
Preload->>IPC: invoke 'update-client-jar-ttl'
IPC->>Dir: updateClientJarTTL(version)
Dir-->>IPC: { success / error }
IPC-->>Preload: result
Preload-->>UI: result (logged if error)
end
rect rgb(245,255,240)
note over UI,Dir: Cleanup old jars (exclude latest)
UI->>Preload: cleanUnusedClients(latestVersion)
Preload->>IPC: invoke 'cleanup-unused-clients-jar'
IPC->>Dir: cleanupUnusedClientsJar(latestVersion)
Dir-->>IPC: { success / error }
IPC-->>Preload: result
Preload-->>UI: result (logged if error)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
Pre-merge checks (3 passed)✅ Passed checks (3 passed)
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
libs/ipc-handlers.js (1)
15-16: Broken base URL (missing slash) prevents version fetches.
'https:/microbot.cloud' should be 'https://microbot.cloud'.Apply this diff:
- const url = 'https:/microbot.cloud'; + const url = 'https://microbot.cloud';
🧹 Nitpick comments (8)
libs/dir-module.js (4)
78-101: Initialize TTL file more defensively (encoding + shape guard).
Explicitly set encoding when creating the file and coerce malformed JSON to an object to avoid downstream crashes.Apply this diff:
- const data = await fs.readFile(filePath, 'utf8'); - return { success: true, data: JSON.parse(data) }; + const data = await fs.readFile(filePath, 'utf8'); + let parsed = JSON.parse(data); + if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) { + parsed = {}; + } + return { success: true, data: parsed }; } catch (readErr) { if (readErr.code === 'ENOENT') { - await fs.writeFile(filePath, JSON.stringify({})); + await fs.writeFile(filePath, JSON.stringify({}), 'utf8'); return { success: true, data: {} };
121-140: Minor nits: hoist now() and tighten version parsing.
- Use a single const now = Date.now() for the whole function for consistency.
- Consider extracting version via a regex (e.g., /^microbot-(.+).jar$/) to avoid edge cases.
146-169: Return deletion stats and remove unused variable.
deletedAny is set but unused. Returning a count helps telemetry and debugging.Apply this diff:
- let deletedAny = false; + let deletedCount = 0; @@ - delete ttlData[version]; - deletedAny = true; + delete ttlData[version]; + deletedCount += 1; updated = true; @@ - if (!updated) { - return { success: true }; - } + if (!updated) { + return { success: true, deleted: 0 }; + } @@ - return { success: true }; + return { success: true, deleted: deletedCount };
185-207: updateClientJarTTL: solid; consider light input hardening.
Optionally reject unexpected version strings (e.g., /^[A-Za-z0-9._-]+$/) to keep TTL keys clean.libs/ipc-handlers.js (2)
297-307: IPC handler wiring for cleanup — looks good; schedule periodically.
The channel is correct. Consider scheduling a daily cleanup in the main process (e.g., setInterval) in addition to on-demand invocations to keep disk usage in check.
314-321: IPC handler for TTL update — looks good; validate inputs.
Add a quick typeof/version-pattern check before invoking to fail fast on bad renderer calls.preload.js (1)
51-54: Add param normalization + tiny docs on new bridge APIs.Minor: coerce params to strings and document expected shapes to avoid accidental non-string payloads crossing IPC.
openLocation: (locationKey) => ipcRenderer.invoke('open-location', locationKey), - cleanUnusedClients: (latestVersion) => - ipcRenderer.invoke('cleanup-unused-clients-jar', latestVersion), - updateClientJarTTL: (version) => - ipcRenderer.invoke('update-client-jar-ttl', version), + /** Delete stale client jars except the latest. latestVersion: "1.2.3.4" */ + cleanUnusedClients: (latestVersion) => + ipcRenderer.invoke('cleanup-unused-clients-jar', String(latestVersion)), + /** Update "last launched" timestamp. version: "1.2.3.4" */ + updateClientJarTTL: (version) => + ipcRenderer.invoke('update-client-jar-ttl', String(version)),renderer.js (1)
241-244: Normalize version before cleanup & avoidresultshadowingTrim any leading "microbot-" from clientVersion before calling cleanUnusedClients (libs/dir-module.js strips "microbot-" from jar filenames), and use a distinct response variable name for clarity.
Location: renderer.js lines 241–244.
- const result = await window.electron.cleanUnusedClients(clientVersion); - if (result?.error) { - window.electron.logError(result.error); - } + const latestVersion = clientVersion?.replace(/^microbot-/, ''); + const cleanupRes = await window.electron.cleanUnusedClients(latestVersion); + if (cleanupRes?.error) { + window.electron.logError(cleanupRes.error); + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
libs/dir-module.js(1 hunks)libs/ipc-handlers.js(1 hunks)libs/properties.js(0 hunks)package.json(1 hunks)preload.js(1 hunks)renderer.js(3 hunks)
💤 Files with no reviewable changes (1)
- libs/properties.js
🧰 Additional context used
🧬 Code graph analysis (3)
preload.js (2)
renderer.js (2)
latestVersion(1048-1050)version(22-22)libs/dir-module.js (1)
version(133-133)
libs/ipc-handlers.js (2)
main.js (6)
require(1-1)require(6-6)require(8-8)require(11-11)require(12-16)path(2-2)libs/dir-module.js (2)
path(2-2)version(133-133)
libs/dir-module.js (3)
main.js (6)
require(1-1)require(6-6)require(8-8)require(11-11)require(12-16)path(2-2)libs/ipc-handlers.js (6)
require(18-22)require(23-27)require(300-304)require(315-319)result(242-246)result(272-281)renderer.js (6)
result(24-24)result(42-42)result(228-228)result(241-241)result(556-556)version(22-22)
🔇 Additional comments (2)
package.json (1)
3-3: Version bump to 3.2.3 — LGTM.
No issues spotted in this file.libs/dir-module.js (1)
211-215: Exports — LGTM.
Matches new API surface and existing imports.
- Avoid aborting the cleanup process on manual file deletion coming from the user. Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
libs/dir-module.js (1)
160-167: Nice: ENOENT during unlink is handled without aborting cleanup.This addresses the earlier feedback about missing-file races.
🧹 Nitpick comments (4)
libs/dir-module.js (4)
78-82: Correct JSDoc return type for getClientsJarTTL.Document the actual
{ success, data?, error? }shape./** * Check for the existence of the clients_jar_ttl.json file in the microbot directory. * Creating with an empty object if it does not exist. - * @return {Object} The parsed JSON object from the file. + * @return {Promise<{success: boolean, data?: Record<string, number>, error?: string}>} */
89-97: Recover gracefully from corrupted clients_jar_ttl.json.If the file is malformed JSON, back it up and reset instead of failing.
- const data = await fs.readFile(filePath, 'utf8'); - return { success: true, data: JSON.parse(data) }; + const data = await fs.readFile(filePath, 'utf8'); + try { + return { success: true, data: JSON.parse(data) }; + } catch (parseErr) { + // Recover from corruption: back up and reset. + const backup = filePath + '.bak'; + await fs.copyFile(filePath, backup).catch(() => {}); + await fs.writeFile(filePath, JSON.stringify({}), 'utf8'); + return { success: true, data: {} }; + }
176-181: Reduce lost updates from concurrent writers by merging on-disk TTL before write.Helps when cleanup and TTL updates run at the same time.
const filePath = path.join(microbotDir, 'clients_jar_ttl.json'); try { + // Merge with latest on-disk TTL to minimize clobbering concurrent updates. + try { + const onDiskRaw = await fs.readFile(filePath, 'utf8').catch(() => null); + if (onDiskRaw) { + const onDisk = JSON.parse(onDiskRaw); + ttlData = { ...onDisk, ...ttlData }; + } + } catch (_) { /* ignore parse errors */ } await fs.writeFile(filePath, JSON.stringify(ttlData, null, 2), 'utf8'); } catch (err) { return { success: false, error: err.message }; }
146-147: Remove unused variable deletedAny.It’s assigned but never read.
- let deletedAny = false; ... - deletedAny = true;Also applies to: 157-157
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
libs/dir-module.js(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: Bolado
PR: chsami/Microbot-Launcher#25
File: renderer.js:42-45
Timestamp: 2025-09-11T19:35:56.332Z
Learning: In the Microbot Launcher, updating client JAR TTL should happen based on user intent to launch (before actual launch) rather than after successful launch, because failed launches due to technical issues shouldn't prevent keeping versions that users want to use.
🧬 Code graph analysis (1)
libs/dir-module.js (3)
main.js (6)
require(1-1)require(6-6)require(8-8)require(11-11)require(12-16)path(2-2)libs/ipc-handlers.js (6)
require(18-22)require(23-27)require(300-304)require(315-319)result(242-246)result(272-281)renderer.js (6)
result(24-24)result(42-42)result(228-228)result(241-241)result(556-556)version(22-22)
🔇 Additional comments (1)
libs/dir-module.js (1)
217-220: Exports update looks good.Public API surface aligns with new functionality.
- Add version format validation for client jar updates - Check for existence of the jar file before updating - Return specific error messages for invalid inputs and missing jars
Client executables will be tracked based on their most recent launch time. Initially, all existing clients on the user's machine will have their "last launched time" set to the current time. Versions not yet tracked are added to the JSON file with the current time whenever user opens the launcher. Whenever a client .jar is launched, its "last launched time" is updated to the current time. If a client .jar is not launched for three days, it is deleted unless it is the latest available version, which is always retained.
Github Copilot Summary
This pull request introduces a system for tracking and cleaning up unused client JAR files in the
microbotDir, ensuring only recently used and the latest client versions are retained. It does this by recording last-used timestamps in a JSON file and providing routines to update and clean up these files, which are integrated into the application's IPC and renderer logic. Additionally, some minor cleanup and version bumping are included.Client JAR TTL management and cleanup:
getClientsJarTTL,cleanupUnusedClientsJar, andupdateClientJarTTLfunctions todir-module.jsto track last-used timestamps for each client JAR, delete unused JARs older than 3 days (except the latest), and update usage timestamps.ipc-handlers.jsfor cleaning up unused client JARs and updating TTL data, allowing renderer processes to trigger these actions.cleanUnusedClientsandupdateClientJarTTLmethods to the Electron context bridge inpreload.jsfor renderer access.Renderer integration:
renderer.jsto callupdateClientJarTTLwhenever a client is opened or played, and to triggercleanUnusedClientson load, logging errors if any occur. [1] [2] [3]Miscellaneous:
launcher,launcher_html) fromproperties.jsfor cleanup.3.2.3inpackage.json.Summary by CodeRabbit
New Features
Chores