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
+}

Reply via email to