mirror of
https://github.com/stablyai/orca.git
synced 2026-10-01 00:02:10 +00:00
perf(relay): stop the port scan walking all of procfs after every socket has an owner
This commit is contained in:
@@ -119,6 +119,31 @@ function mockLinuxProcScan({
|
||||
})
|
||||
}
|
||||
|
||||
describe('PortScanHandler Linux walk bounds', () => {
|
||||
it('stops walking procfs once every listening socket has an owner', async () => {
|
||||
// Why: this scan repeats for the life of the session, and its unit cost was O(all host
|
||||
// processes x all fds) regardless of how few sockets it was resolving. On a busy remote the
|
||||
// process count only climbs, so the scan got permanently more expensive -- the shape behind
|
||||
// "SSH degrades the longer Orca stays open". One listener means one readlink, not 100,000.
|
||||
mockLinuxProcScan({ pidCount: 1_000, fdCount: 100 })
|
||||
|
||||
await capturePortDetectHandler()({}, requestContext())
|
||||
|
||||
expect(readlinkMock).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('still walks the whole table when a socket has no reachable owner', async () => {
|
||||
// The inverse: an unattributable inode (another user's process) must not make the scan give up
|
||||
// early on sockets it could still attribute.
|
||||
mockLinuxProcScan({ pidCount: 3, fdCount: 2 })
|
||||
readlinkMock.mockImplementation(() => Promise.resolve('socket:[99999]'))
|
||||
|
||||
await capturePortDetectHandler()({}, requestContext())
|
||||
|
||||
expect(readlinkMock).toHaveBeenCalledTimes(6)
|
||||
})
|
||||
})
|
||||
|
||||
describe('PortScanHandler Linux cancellation', () => {
|
||||
it('does not touch procfs for an already-cancelled request', async () => {
|
||||
const controller = new AbortController()
|
||||
|
||||
@@ -161,6 +161,13 @@ export class PortScanHandler {
|
||||
|
||||
for (const pidStr of pids) {
|
||||
signal?.throwIfAborted()
|
||||
// Why: every remaining pid costs a readdir plus one readlink per fd, and this scan repeats for
|
||||
// the life of the session. Without this the walk was O(all host processes x all fds) even once
|
||||
// every listener was already attributed, so its cost grew with the remote's process count and
|
||||
// never came back down — the shape behind "SSH gets slower the longer Orca stays open".
|
||||
if (result.size === inodes.size) {
|
||||
return result
|
||||
}
|
||||
const fdDir = `/proc/${pidStr}/fd`
|
||||
let fds: string[]
|
||||
try {
|
||||
@@ -192,6 +199,9 @@ export class PortScanHandler {
|
||||
const inode = Number.parseInt(match[1], 10)
|
||||
if (inodes.has(inode)) {
|
||||
result.set(inode, pid)
|
||||
if (result.size === inodes.size) {
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user