This is an automated email from the ASF dual-hosted git repository.
rstrickland pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil-vscode.git
The following commit(s) were added to refs/heads/main by this push:
new fc11fbd Reworked Data Editor Heartbeat Structure - Resolved continous
logging of `getServerHeartbeat` requests - Extracted heartbeat functionality
from DataEditorClient
fc11fbd is described below
commit fc11fbd4f56d60082e7bde6ace52b810c8fd8b88
Author: Robert Strickland <[email protected]>
AuthorDate: Fri Feb 28 16:11:18 2025 -0600
Reworked Data Editor Heartbeat Structure
- Resolved continous logging of `getServerHeartbeat` requests
- Extracted heartbeat functionality from DataEditorClient
Closes #1021
---
src/dataEditor/dataEditorClient.ts | 115 ++++-----------------
src/dataEditor/include/server/Sessions.ts | 34 ++++++
.../include/server/heartbeat/HeartBeatInfo.ts | 10 +-
src/dataEditor/include/server/heartbeat/index.ts | 41 ++++++++
4 files changed, 97 insertions(+), 103 deletions(-)
diff --git a/src/dataEditor/dataEditorClient.ts
b/src/dataEditor/dataEditorClient.ts
index d1109d9..1c9d9a9 100644
--- a/src/dataEditor/dataEditorClient.ts
+++ b/src/dataEditor/dataEditorClient.ts
@@ -25,7 +25,6 @@ import {
createSimpleFileLogger,
createViewport,
del,
- destroySession,
edit,
EditorClient,
endSessionTransaction,
@@ -38,11 +37,9 @@ import {
getCounts,
getLanguage,
getLogger,
- getServerHeartbeat,
getServerInfo,
getViewportData,
IOFlags,
- IServerInfo,
modifyViewport,
numAscii,
profileSession,
@@ -77,17 +74,14 @@ import {
MessageLevel,
} from '../svelte/src/utilities/message'
import * as editor_config from './config'
-import {
- HeartbeatInfo,
- IHeartbeatInfo,
-} from './include/server/heartbeat/HeartBeatInfo'
-import {
- configureOmegaEditPort,
- ServerInfo,
- ServerStopPredicate,
-} from './include/server/ServerInfo'
+import { configureOmegaEditPort, ServerInfo } from
'./include/server/ServerInfo'
import { isDFDLDebugSessionActive } from './include/utils'
import { SvelteWebviewInitializer } from './svelteWebviewInitializer'
+import {
+ addActiveSession,
+ removeActiveSession,
+} from './include/server/Sessions'
+import { getCurrentHeartbeatInfo } from './include/server/heartbeat'
//
*****************************************************************************
// global constants
@@ -108,13 +102,9 @@ const MAX_LOG_FILES: number = 5 // Maximum number of log
files to keep TODO: mak
//
*****************************************************************************
// file-scoped variables
//
*****************************************************************************
-
-let activeSessions: string[] = []
+let serverInfo: ServerInfo = new ServerInfo()
let checkpointPath: string = ''
let client: EditorClient
-let getHeartbeatIntervalId: NodeJS.Timeout | number | undefined = undefined
-let heartbeatInfo: IHeartbeatInfo = new HeartbeatInfo()
-let serverInfo: IServerInfo = new ServerInfo()
let omegaEditPort: number = 0
//
*****************************************************************************
@@ -162,6 +152,7 @@ export class DataEditorClient implements vscode.Disposable {
})
this.panel.webview.onDidReceiveMessage(this.messageReceiver, this)
this.panel.onDidDispose(async () => {
+ await removeActiveSession(this.omegaSessionId)
await this.dispose()
})
this.disposables.push(
@@ -187,20 +178,12 @@ export class DataEditorClient implements
vscode.Disposable {
addDisposable(dispoable: vscode.Disposable) {
this.disposables.push(dispoable)
}
- dispose(): void {
+ async dispose(): Promise<void> {
if (this.sendHeartbeatIntervalId) {
clearInterval(this.sendHeartbeatIntervalId)
this.sendHeartbeatIntervalId = undefined
}
- // destroy the session and remove it from the list of active sessions
- destroySession(this.omegaSessionId).then((id) => {
- removeActiveSession(id)
- serverStopIf(() => {
- return activeSessions.length == 0
- })
- })
-
for (let i = 0; i < this.disposables.length; i++)
this.disposables[i].dispose()
}
@@ -342,6 +325,8 @@ export class DataEditorClient implements vscode.Disposable {
}
private async sendHeartbeat() {
+ const heartbeatInfo = getCurrentHeartbeatInfo()
+
await this.panel.webview.postMessage({
command: MessageCommand.heartbeat,
data: {
@@ -353,13 +338,13 @@ export class DataEditorClient implements
vscode.Disposable {
sessionCount: heartbeatInfo.sessionCount,
serverInfo: {
omegaEditPort: this.configVars.port,
- serverVersion: heartbeatInfo.serverInfo.serverVersion,
- serverHostname: heartbeatInfo.serverInfo.serverHostname,
- serverProcessId: heartbeatInfo.serverInfo.serverProcessId,
- jvmVersion: heartbeatInfo.serverInfo.jvmVersion,
- jvmVendor: heartbeatInfo.serverInfo.jvmVendor,
- jvmPath: heartbeatInfo.serverInfo.jvmPath,
- availableProcessors: heartbeatInfo.serverInfo.availableProcessors,
+ serverVersion: serverInfo.serverVersion,
+ serverHostname: serverInfo.serverHostname,
+ serverProcessId: serverInfo.serverProcessId,
+ jvmVersion: serverInfo.jvmVersion,
+ jvmVendor: serverInfo.jvmVendor,
+ jvmPath: serverInfo.jvmPath,
+ availableProcessors: serverInfo.availableProcessors,
},
},
})
@@ -848,12 +833,6 @@ async function createDataEditorWebviewPanel(
await checkServerListening(omegaEditPort, OMEGA_EDIT_HOST),
'server not listening'
)
- // initialize the first server heartbeat
- await getHeartbeat()
- assert(
- heartbeatInfo.serverInfo.serverVersion.length > 0,
- 'heartbeat did not receive a server version'
- )
}
fileToEdit = fileToEdit.replace(
editor_config.WorkspaceKeyword,
@@ -1132,9 +1111,7 @@ function removeDirectory(dirPath: string): void {
fs.rmdirSync(dirPath)
}
}
-async function serverStopIf(predicate: ServerStopPredicate) {
- if (predicate()) await serverStop()
-}
+
async function serverStop() {
const serverPidFile = getPidFile(omegaEditPort)
if (fs.existsSync(serverPidFile)) {
@@ -1188,57 +1165,6 @@ function generateLogbackConfigFile(
return logbackConfigFile // Return the path to the logback config file
}
-function addActiveSession(sessionId: string): void {
- if (!activeSessions.includes(sessionId)) {
- activeSessions.push(sessionId)
- // scale the heartbeat interval based on the number of active sessions to
reduce load on the server
- getHeartbeat().then(() => {
- if (getHeartbeatIntervalId) {
- clearInterval(getHeartbeatIntervalId)
- }
- getHeartbeatIntervalId = setInterval(async () => {
- await getHeartbeat()
- }, HEARTBEAT_INTERVAL_MS * activeSessions.length)
- })
- }
-}
-
-function removeActiveSession(sessionId: string): void {
- const index = activeSessions.indexOf(sessionId)
- if (index >= 0) {
- activeSessions.splice(index, 1)
- clearInterval(getHeartbeatIntervalId)
- getHeartbeatIntervalId = undefined
- if (activeSessions.length > 0) {
- // scale the heartbeat interval based on the number of active sessions
- getHeartbeat().then(() => {
- getHeartbeatIntervalId = setInterval(async () => {
- await getHeartbeat()
- }, HEARTBEAT_INTERVAL_MS * activeSessions.length)
- })
- }
- }
-}
-
-async function getHeartbeat() {
- assert(omegaEditPort > 0, `illegal Ωedit port ${omegaEditPort}`)
- const heartbeat = await getServerHeartbeat(
- activeSessions,
- HEARTBEAT_INTERVAL_MS
- )
- heartbeatInfo.omegaEditPort = omegaEditPort
- heartbeatInfo.latency = heartbeat.latency
- heartbeatInfo.serverCommittedMemory = heartbeat.serverCommittedMemory
- heartbeatInfo.serverCpuCount = heartbeat.serverCpuCount
- heartbeatInfo.serverCpuLoadAverage = heartbeat.serverCpuLoadAverage
- heartbeatInfo.serverMaxMemory = heartbeat.serverMaxMemory
- heartbeatInfo.serverTimestamp = heartbeat.serverTimestamp
- heartbeatInfo.serverUptime = heartbeat.serverUptime
- heartbeatInfo.serverUsedMemory = heartbeat.serverUsedMemory
- heartbeatInfo.sessionCount = heartbeat.sessionCount
- heartbeatInfo.serverInfo = serverInfo
-}
-
async function serverStart() {
await serverStop()
const serverStartingText = `Ωedit server starting on port ${omegaEditPort}`
@@ -1337,8 +1263,7 @@ async function serverStart() {
`Server version ${serverVersion} and client version ${clientVersion}
must match`
)
}
- // get an initial heartbeat
- await getHeartbeat()
+
statusBarItem.text = `Ωedit server v${serverVersion} ready on port
${omegaEditPort} with PID ${serverInfo.serverProcessId}`
setTimeout(() => {
statusBarItem.dispose()
diff --git a/src/dataEditor/include/server/Sessions.ts
b/src/dataEditor/include/server/Sessions.ts
new file mode 100644
index 0000000..4c462e1
--- /dev/null
+++ b/src/dataEditor/include/server/Sessions.ts
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { destroySession } from '@omega-edit/client'
+import { updateHeartbeatInterval } from './heartbeat'
+
+let activeSessions: string[] = []
+
+export function addActiveSession(sessionId: string): void {
+ if (!activeSessions.includes(sessionId)) {
+ activeSessions.push(sessionId)
+ // scale the heartbeat interval based on the number of active sessions to
reduce load on the server
+ updateHeartbeatInterval(activeSessions)
+ }
+}
+export async function removeActiveSession(sessionId: string) {
+ const index = activeSessions.indexOf(sessionId)
+ activeSessions.splice(index, 1)
+ updateHeartbeatInterval(activeSessions)
+ await destroySession(sessionId)
+}
diff --git a/src/dataEditor/include/server/heartbeat/HeartBeatInfo.ts
b/src/dataEditor/include/server/heartbeat/HeartBeatInfo.ts
index 4825158..5999dc3 100644
--- a/src/dataEditor/include/server/heartbeat/HeartBeatInfo.ts
+++ b/src/dataEditor/include/server/heartbeat/HeartBeatInfo.ts
@@ -14,14 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { IServerHeartbeat, IServerInfo } from '@omega-edit/client'
-import { ServerInfo } from '../ServerInfo'
+import { IServerHeartbeat } from '@omega-edit/client'
-export interface IHeartbeatInfo extends IServerHeartbeat {
- omegaEditPort: number // Ωedit server port
- serverInfo: IServerInfo // server info that remains constant
-}
-export class HeartbeatInfo {
+export class HeartbeatInfo implements IServerHeartbeat {
omegaEditPort: number = 0 // Ωedit server port
latency: number = 0 // latency in ms
serverCommittedMemory: number = 0 // committed memory in bytes
@@ -32,5 +27,4 @@ export class HeartbeatInfo {
serverUptime: number = 0 // uptime in ms
serverUsedMemory: number = 0 // used memory in bytes
sessionCount: number = 0 // session count
- serverInfo: IServerInfo = new ServerInfo()
}
diff --git a/src/dataEditor/include/server/heartbeat/index.ts
b/src/dataEditor/include/server/heartbeat/index.ts
new file mode 100644
index 0000000..71c33b3
--- /dev/null
+++ b/src/dataEditor/include/server/heartbeat/index.ts
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { getServerHeartbeat, IServerHeartbeat } from '@omega-edit/client'
+import { HeartbeatInfo } from './HeartBeatInfo'
+
+const HEARTBEAT_INTERVAL_MS: number = 1000 // 1 second (1000 ms)
+let heartbeatInfo: IServerHeartbeat = new HeartbeatInfo()
+let getHeartbeatIntervalId: NodeJS.Timeout | number | undefined = undefined
+
+export function updateHeartbeatInterval(activeSessions: string[]) {
+ if (getHeartbeatIntervalId) {
+ clearInterval(getHeartbeatIntervalId)
+ }
+ getHeartbeatIntervalId =
+ activeSessions.length > 0
+ ? setInterval(async () => {
+ heartbeatInfo = await getServerHeartbeat(
+ activeSessions,
+ HEARTBEAT_INTERVAL_MS * activeSessions.length
+ )
+ })
+ : undefined
+}
+
+export function getCurrentHeartbeatInfo() {
+ return heartbeatInfo
+}