Skip to content

Commit d574674

Browse files
authored
Merge branch 'main' into scala_update
2 parents 7f724c0 + 91770bd commit d574674

File tree

13 files changed

+253
-94
lines changed

13 files changed

+253
-94
lines changed

.github/workflows/release.yml

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# Copyright (c) 2021 Concurrent Technologies Corporation.
2-
#
2+
#
33
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
4-
# with the License. You may obtain a copy of the License at
5-
#
6-
# http://www.apache.org/licenses/LICENSE-2.0
7-
#
8-
# Unless required by applicable law or agreed to in writing, software is distributed under the License is
9-
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
10-
# implied. See the License for the specific language governing permissions and limitations under the License.
4+
# with the License. You may obtain a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software is distributed under the License is
9+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
10+
# implied. See the License for the specific language governing permissions and limitations under the License.
1111

1212
---
1313
name: Automatic Release
@@ -16,7 +16,7 @@ on:
1616
tags:
1717
- 'v*.*.*'
1818
env:
19-
node_version: 16
19+
node_version: 18
2020
export_cmd: |
2121
GIT_TAG=$(echo ${GITHUB_REF#refs/*/} | cut -d 'v' -f 2)
2222
PKG_VERSION=$(echo $(node -p "JSON.stringify(require('./package.json').version)") | sed 's|"||g')
@@ -42,7 +42,7 @@ jobs:
4242
# This check name is defined as the github action job name (in .github/workflows/testing.yaml)
4343
checkName: "Rat Check 🐀"
4444
ref: ${{ github.event.pull_request.head.sha || github.sha }}
45-
45+
4646
- name: Check Scala format ✅
4747
uses: fountainhead/[email protected]
4848
id: scala-format
@@ -51,7 +51,7 @@ jobs:
5151
# This check name is defined as the github action job name (in .github/workflows/testing.yaml)
5252
checkName: "Scala Code Format"
5353
ref: ${{ github.event.pull_request.head.sha || github.sha }}
54-
54+
5555
- name: Check TypeScript format ✅
5656
uses: fountainhead/[email protected]
5757
id: ts-format
@@ -60,7 +60,7 @@ jobs:
6060
# This check name is defined as the github action job name (in .github/workflows/testing.yaml)
6161
checkName: "TypeScript code is properly formatted"
6262
ref: ${{ github.event.pull_request.head.sha || github.sha }}
63-
63+
6464
- name: Check tests - macOS 12 ✅
6565
uses: fountainhead/[email protected]
6666
id: macos12-tests
@@ -69,7 +69,7 @@ jobs:
6969
# This check name is defined as the github action job name (in .github/workflows/testing.yaml)
7070
checkName: "Build middleware macos-12 🔧"
7171
ref: ${{ github.event.pull_request.head.sha || github.sha }}
72-
72+
7373
- name: Check tests - macOS 14 ✅
7474
uses: fountainhead/[email protected]
7575
id: macos14-tests
@@ -96,7 +96,7 @@ jobs:
9696
# This check name is defined as the github action job name (in .github/workflows/testing.yaml)
9797
checkName: "Build middleware windows-2019 🔧"
9898
ref: ${{ github.event.pull_request.head.sha || github.sha }}
99-
99+
100100
- name: Check native build arm64 - Linux ✅
101101
uses: fountainhead/[email protected]
102102
id: ubuntu-arm64-native
@@ -178,7 +178,7 @@ jobs:
178178
- name: Export git tag and package.json version 🚢
179179
run: ${{ env.export_cmd }}
180180
shell: bash
181-
181+
182182
- name: Download upload_url 🔻
183183
uses: actions/download-artifact@v4
184184
with:
@@ -195,7 +195,7 @@ jobs:
195195
distribution: temurin
196196
java-version: 8
197197
cache: sbt
198-
198+
199199
- name: Make _install directory to store lib files
200200
run: mkdir -p _install
201201

@@ -207,7 +207,7 @@ jobs:
207207
workflow_conclusion: success
208208
name: ubuntu-20.04-x64-libomega_edit.so
209209
path: _install/libomega_edit_linux_amd64.so
210-
210+
211211
- name: Download linux arm64 library file 🔻
212212
uses: dawidd6/action-download-artifact@v3
213213
with:
@@ -216,7 +216,7 @@ jobs:
216216
workflow_conclusion: success
217217
name: ubuntu-20.04-arm64-libomega_edit.so
218218
path: _install/libomega_edit_linux_aarch64.so
219-
219+
220220
- name: Download macos-12 library file 🔻
221221
uses: dawidd6/action-download-artifact@v3
222222
with:
@@ -234,7 +234,7 @@ jobs:
234234
workflow_conclusion: success
235235
name: macos-12-x64-libomega_edit.dylib
236236
path: _install/libomega_edit_macos_x86_64.dylib
237-
237+
238238
- name: Download windows library file 🔻
239239
uses: dawidd6/action-download-artifact@v3
240240
with:

.github/workflows/ts-format.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ jobs:
2929
with:
3030
fetch-depth: 0
3131
persist-credentials: false
32-
32+
3333
- name: Setup Node 📐
3434
uses: actions/setup-node@v4
3535
with:
3636
registry-url: 'https://registry.npmjs.org'
37-
node-version: 16
37+
node-version: 18
3838

3939
- name: yarn lint - all workspaces 🧶
4040
run: |

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"typedoc": "^0.25.13",
3939
"typescript": "^5.4.5",
4040
"unzip-stream": "^0.3.4",
41-
"webpack": "^5.91.0",
41+
"webpack": "^5.95.0",
4242
"webpack-cli": "^5.1.4"
4343
},
4444
"prettier": {

packages/client/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@
4343
"ts-node": "^10.9.2"
4444
},
4545
"dependencies": {
46-
"@grpc/grpc-js": "1.10.9",
46+
"@grpc/grpc-js": "1.12.2",
4747
"@omega-edit/server": "0.9.82",
4848
"@types/google-protobuf": "3.15.12",
49-
"google-protobuf": "3.21.2",
50-
"pid-port": "0.2.0",
51-
"pino": "8.20.0",
49+
"google-protobuf": "3.21.4",
50+
"pid-port": "1.0.0",
51+
"pino": "9.5.0",
5252
"wait-port": "1.1.0"
5353
}
5454
}

packages/client/src/server.ts

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ import {
3333
ServerControlResponse,
3434
ServerInfoResponse,
3535
} from './omega_edit_pb'
36+
import { execFile } from 'child_process'
37+
import { promisify } from 'util'
38+
39+
// Convert execFile to a promise-based function
40+
const execFilePromise = promisify(execFile)
3641

3742
const DEFAULT_PORT = 9000 // default port for the server
3843
const DEFAULT_HOST = '127.0.0.1' // default host for the server
@@ -271,6 +276,36 @@ export async function stopProcessUsingPID(
271276
return true
272277
}
273278

279+
/**
280+
* Get the process id using the port
281+
* @param port port to check
282+
* @returns process id or undefined if the port is not in use
283+
*/
284+
async function getPidByPort(port: number): Promise<number | undefined> {
285+
try {
286+
// Try to get the PID using `lsof`
287+
const { stdout } = await execFilePromise('lsof', [
288+
'-iTCP:' + port,
289+
'-sTCP:LISTEN',
290+
'-n',
291+
'-P',
292+
])
293+
const lines = stdout.trim().split('\n')
294+
if (lines.length > 1) {
295+
const [_, pid] = lines[1].trim().split(/\s+/)
296+
return parseInt(pid, 10)
297+
}
298+
return undefined
299+
} catch (error) {
300+
// Fallback to `portToPid` if `lsof` fails
301+
try {
302+
return await portToPid(port)
303+
} catch (portToPidError) {
304+
return undefined
305+
}
306+
}
307+
}
308+
274309
/**
275310
* Stop the service running on a port
276311
* @param port port
@@ -288,21 +323,42 @@ export async function stopServiceOnPort(
288323
signal,
289324
}
290325
log.debug(logMetadata)
326+
291327
try {
292-
const pid = await portToPid(port)
293-
return pid ? stopProcessUsingPID(pid as number, signal) : true
328+
// Attempt to get the PID for the given port
329+
const pid = await getPidByPort(port)
330+
331+
if (pid) {
332+
log.debug({ ...logMetadata, msg: `Found PID ${pid} for port ${port}` })
333+
334+
// Attempt to stop the process using the PID
335+
const result = await stopProcessUsingPID(pid, signal)
336+
log.debug({
337+
...logMetadata,
338+
msg: `stopProcessUsingPID result: ${result}`,
339+
})
340+
return result
341+
} else {
342+
log.debug({
343+
...logMetadata,
344+
stopped: true,
345+
msg: 'No process found using the port',
346+
})
347+
return true // No process was using the port, so consider it as stopped
348+
}
294349
} catch (err) {
350+
// Handle case where `portToPid` cannot find a process for the port
295351
if (err instanceof Error) {
296352
if (err.message.startsWith('Could not find a process that uses port')) {
297353
log.debug({
298354
...logMetadata,
299355
stopped: true,
300356
msg: err.message,
301357
})
302-
// if the port is not in use, return true
303-
return true
358+
return true // No process using the port, so we consider it stopped
304359
}
305-
log.debug({
360+
// Log other types of errors that occur
361+
log.error({
306362
...logMetadata,
307363
stopped: false,
308364
err: {
@@ -317,8 +373,8 @@ export async function stopServiceOnPort(
317373
err: { msg: String(err) },
318374
})
319375
}
376+
return false // Return false for any errors that occur
320377
}
321-
return false
322378
}
323379

324380
/**
@@ -601,7 +657,10 @@ export function pidIsRunning(pid) {
601657
process.kill(pid, 0)
602658
return true
603659
} catch (e) {
604-
return false
660+
if ((e as NodeJS.ErrnoException).code === 'ESRCH') {
661+
return false
662+
}
663+
throw e
605664
}
606665
}
607666

packages/client/tests/specs/common.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,13 @@ export async function subscribeViewport(
171171
: 1
172172
)
173173
const event = viewportEvent.getViewportEventKind()
174+
const viewport_id_from_event = viewportEvent.getViewportId()
174175
if (ViewportEventKind.VIEWPORT_EVT_EDIT == event) {
175176
log_info(
176177
'viewport_id: ' +
177178
viewport_id +
179+
', viewport_id_from_event: ' +
180+
viewport_id_from_event +
178181
', event: ' +
179182
event +
180183
', serial: ' +
@@ -188,6 +191,15 @@ export async function subscribeViewport(
188191
'", callbacks: ' +
189192
viewport_callbacks.get(viewport_id)
190193
)
194+
if (viewport_id_from_event !== viewport_id) {
195+
log_error(
196+
'viewport ID mismatch: "' +
197+
viewport_id +
198+
'" not equal to "' +
199+
viewport_id_from_event +
200+
'"'
201+
)
202+
}
191203
} else {
192204
log_info(
193205
'viewport: ' +

packages/client/tests/specs/viewport.spec.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,12 +176,15 @@ describe('Viewports', () => {
176176
await checkCallbackCount(viewport_callbacks, viewport_1_id, 1)
177177
await checkCallbackCount(viewport_callbacks, viewport_2_id, 3)
178178
log_info(viewport_callbacks)
179+
179180
// Unsubscribe all viewporta
180-
await unsubscribeViewport(viewport_1_id)
181-
await unsubscribeViewport(viewport_2_id)
181+
expect(await unsubscribeViewport(viewport_1_id)).to.equal(viewport_1_id)
182+
expect(await unsubscribeViewport(viewport_2_id)).to.equal(viewport_2_id)
183+
182184
// Note the viewports are not destroyed, just unsubscribed
183185
expect(await getViewportCount(session_id)).to.equal(1)
184-
await destroyViewport(viewport_1_id)
186+
187+
expect(await destroyViewport(viewport_1_id)).to.equal(viewport_1_id)
185188
expect(await getViewportCount(session_id)).to.equal(0)
186189
}).timeout(8000)
187190

@@ -304,6 +307,7 @@ describe('Viewports', () => {
304307
false
305308
)
306309
const viewport_id = viewport_response.getViewportId()
310+
expect(viewport_id).to.equal(session_id + ':' + desired_viewport_id)
307311
expect(await viewportHasChanges(viewport_id)).to.be.false
308312
expect(viewport_response.getData_asU8()).to.deep.equal(Buffer.from(''))
309313
expect(viewport_response.getLength()).to.equal(0)
@@ -414,7 +418,9 @@ describe('Viewports', () => {
414418
)
415419
expect(await getViewportCount(session_id)).to.equal(1)
416420
// Unsubscribe the viewport
417-
expect(await unsubscribeViewport(viewport_id)).to.equal(desired_viewport_id)
421+
expect(await unsubscribeViewport(viewport_id)).to.equal(
422+
session_id + ':' + desired_viewport_id
423+
)
418424
// Note the viewport is not destroyed, just unsubscribed
419425
expect(await getViewportCount(session_id)).to.equal(1)
420426
await destroyViewport(viewport_id)

packages/server/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ async function executeServer(args: string[]): Promise<ChildProcess> {
9090
cwd: path.dirname(serverScript),
9191
stdio: 'ignore',
9292
detached: true,
93+
shell: os.platform().startsWith('win'), // use shell on Windows because it can't execute scripts directly
9394
})
9495

9596
serverProcess.on('error', (err: Error) => {

server/scala/api/src/main/scala/com/ctc/omega_edit/ViewportImpl.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ private[omega_edit] class ViewportImpl(p: Pointer, i: FFI) extends Viewport {
6767

6868
def modify(offset: Long, capacity: Long, isFloating: Boolean): Boolean =
6969
i.omega_viewport_modify(p, offset, capacity, if (isFloating) 1 else 0) == 0
70+
7071
override def toString: String =
7172
data.mkString // TODO: probably render instead as hex
7273

server/scala/serv/src/main/scala/com/ctc/omega_edit/grpc/EditorService.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ class EditorService(implicit val system: ActorSystem) extends Editor {
444444
ObjectId(in.id) match {
445445
case Viewport.Id(sid, vid) =>
446446
(editors ? ViewportOp(sid, vid, Viewport.Unwatch)).mapTo[Result].map {
447-
case Ok(id) => ObjectId(id)
447+
case Ok(_) => in
448448
case Err(c) => throw grpcFailure(c)
449449
}
450450
case _ =>

0 commit comments

Comments
 (0)