Skip to content

Commit e973953

Browse files
Monitor the sessions that exit with unsaved changes (#1215)
1 parent 8ecffad commit e973953

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

src/daemon/index.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ async function checkJavaExtActivated(_context: vscode.ExtensionContext): Promise
4848
return false;
4949
}
5050

51+
traceSessionStatus(javaExt);
5152
traceJavaExtension(javaExt);
5253
traceLSPPerformance(javaExt);
5354

@@ -168,6 +169,26 @@ async function traceJavaExtension(javaExt: vscode.Extension<any>) {
168169
});
169170
}
170171

172+
function traceSessionStatus(javaExt: vscode.Extension<any>) {
173+
let initHandled: boolean = false;
174+
javaExt.exports?.onDidRequestEnd?.((traceEvent: any) => {
175+
if (initHandled) {
176+
return;
177+
}
178+
179+
if (traceEvent?.type === "initialize") {
180+
initHandled = true;
181+
daemon.logWatcher.checkIfUnsavedWorkspace().then((unsaved) => {
182+
if (unsaved) {
183+
sendInfo("", {
184+
name: "unsaved-workspace",
185+
});
186+
}
187+
});
188+
}
189+
});
190+
}
191+
171192
let corruptedCacheDetected: boolean = false;
172193
async function checkIfJavaServerCrashed(wait: number = 0/*ms*/) {
173194
if (corruptedCacheDetected) {

src/daemon/serverLog/logUtils.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ const MESSAGE_BUILD_JOBS_FINISHED = "!MESSAGE >> build jobs finished";
4040
const STACK_INDICATOR = `${EOL}!STACK `;
4141
const MESSAGE_INDICATOR = `${EOL}!MESSAGE `;
4242
const CORRUPTED_WORKSPACE_INDICATOR = "Caused by: org.eclipse.core.internal.dtree.ObjectNotFoundException:";
43+
const ENTRY_RESOURCE_PLUGIN = "!ENTRY org.eclipse.core.resources";
44+
const MESSAGE_UNSAVED_WORKSPACE = "!MESSAGE The workspace exited with unsaved changes in the previous session; refreshing workspace to recover changes.";
4345

4446
export async function logsForLatestSession(logFilepath: string): Promise<string> {
4547
const content = await fs.promises.readFile(logFilepath, { encoding: 'utf-8' });
@@ -142,6 +144,12 @@ export function containsCorruptedException(log: string): boolean {
142144
return !!find;
143145
}
144146

147+
export function isUnsavedWorkspace(log: string): boolean {
148+
const entries = log.split(LOG_ENTRY_SEPARATOR);
149+
const resourcePluginStartEntry = entries.find(e => e.startsWith(ENTRY_RESOURCE_PLUGIN));
150+
return !!resourcePluginStartEntry?.includes(MESSAGE_UNSAVED_WORKSPACE);
151+
}
152+
145153
function getMessage(entry: string) {
146154
const start = entry.indexOf(MESSAGE_INDICATOR);
147155
if (start < 0) { return ""; }

src/daemon/serverLog/logWatcher.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as path from "path";
66
import * as vscode from "vscode";
77
import { sendInfo } from "vscode-extension-telemetry-wrapper";
88
import { LSDaemon } from "../daemon";
9-
import { collectErrors, collectErrorsSince, containsCorruptedException, logsForLatestSession, sessionMetadata } from "./logUtils";
9+
import { collectErrors, collectErrorsSince, containsCorruptedException, isUnsavedWorkspace, logsForLatestSession, sessionMetadata } from "./logUtils";
1010
import { toElapsed } from "./utils";
1111
import { redact } from "./whitelist";
1212

@@ -135,4 +135,13 @@ export class LogWatcher {
135135

136136
return false;
137137
}
138+
139+
public async checkIfUnsavedWorkspace(): Promise<boolean> {
140+
if (this.serverLogUri) {
141+
const logs = await logsForLatestSession(path.join(this.serverLogUri?.fsPath, ".log"));
142+
return isUnsavedWorkspace(logs);
143+
}
144+
145+
return false;
146+
}
138147
}

0 commit comments

Comments
 (0)