Skip to content

Commit 3aa8a59

Browse files
authored
feat: launch.json option to limit the maximum parallel DBGp connections. (#673)
* launch.json option to limit the maximum parallel DBGp connections. * Test with two connections. * Changelog.
1 parent 08a4735 commit 3aa8a59

File tree

7 files changed

+59
-5
lines changed

7 files changed

+59
-5
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
66

7+
## [1.21.0]
8+
9+
- Support for maxConnections limiting how many parallel connections the debug adapter allows.
10+
711
## [1.20.0]
812

913
- Support no-folder debugging in (purple) VS Code.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ More general information on debugging with VS Code can be found on https://code.
7676
- `pathMappings`: A list of server paths mapping to the local source paths on your machine, see "Remote Host Debugging" below
7777
- `log`: Whether to log all communication between VS Code and the adapter to the debug console. See _Troubleshooting_ further down.
7878
- `ignore`: An optional array of glob patterns that errors should be ignored from (for example `**/vendor/**/*.php`)
79+
- `maxConnections`: Accept only this number of parallel debugging sessions. Additional connections will be dropped and their execution will continue without debugging.
7980
- `xdebugSettings`: Allows you to override Xdebug's remote debugging settings to fine tuning Xdebug to your needs. For example, you can play with `max_children` and `max_depth` to change the max number of array and object children that are retrieved and the max depth in structures like arrays and objects. This can speed up the debugger on slow machines.
8081
For a full list of feature names that can be set please refer to the [Xdebug documentation](https://xdebug.org/docs-dbgp.php#feature-names).
8182
- `max_children`: max number of array or object children to initially retrieve

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,11 @@
275275
},
276276
"description": "Overrides for Xdebug remote debugging settings. See https://xdebug.org/docs-dbgp.php#feature-names",
277277
"default": {}
278+
},
279+
"maxConnections": {
280+
"type": "number",
281+
"description": "The maximum allowed parallel debugging sessions",
282+
"default": 0
278283
}
279284
}
280285
}

src/dbgp.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ export class DbgpConnection extends EventEmitter {
121121
/** closes the underlying socket */
122122
public close(): Promise<void> {
123123
return new Promise<void>((resolve, reject) => {
124+
if (this._socket.destroyed) {
125+
resolve()
126+
return
127+
}
124128
this._socket.once('close', resolve)
125129
this._socket.end()
126130
})

src/phpDebug.ts

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ export interface LaunchRequestArguments extends VSCodeDebugProtocol.LaunchReques
8888
env?: { [key: string]: string }
8989
/** If true launch the target in an external console. */
9090
externalConsole?: boolean
91+
/** Maximum allowed parallel debugging sessions */
92+
maxConnections?: number
9193
}
9294

9395
class PhpDebugSession extends vscode.DebugSession {
@@ -288,21 +290,40 @@ class PhpDebugSession extends vscode.DebugSession {
288290
server.on('connection', async (socket: net.Socket) => {
289291
try {
290292
// new Xdebug connection
293+
// first check if we have a limit on connections
294+
if (args.maxConnections ?? 0 > 0) {
295+
if (this._connections.size >= args.maxConnections!) {
296+
if (args.log) {
297+
this.sendEvent(
298+
new vscode.OutputEvent(
299+
`new connection from ${socket.remoteAddress} - dropping due to max connection limit\n`
300+
),
301+
true
302+
)
303+
}
304+
socket.end()
305+
return
306+
}
307+
}
308+
291309
const connection = new xdebug.Connection(socket)
292310
if (args.log) {
293-
this.sendEvent(new vscode.OutputEvent('new connection ' + connection.id + '\n'), true)
311+
this.sendEvent(
312+
new vscode.OutputEvent(
313+
`new connection ${connection.id} from ${socket.remoteAddress}\n`
314+
),
315+
true
316+
)
294317
}
295318
this._connections.set(connection.id, connection)
296319
const disposeConnection = (error?: Error) => {
297320
if (this._connections.has(connection.id)) {
298321
if (args.log) {
299-
this.sendEvent(new vscode.OutputEvent('connection ' + connection.id + ' closed\n'))
322+
this.sendEvent(new vscode.OutputEvent(`connection ${connection.id} closed\n`))
300323
}
301324
if (error) {
302325
this.sendEvent(
303-
new vscode.OutputEvent(
304-
'connection ' + connection.id + ': ' + error.message + '\n'
305-
)
326+
new vscode.OutputEvent(`connection ${connection.id}: ${error.message}\n`)
306327
)
307328
}
308329
this.sendEvent(new vscode.ContinuedEvent(connection.id, false))

src/test/adapter.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as path from 'path'
44
import { DebugClient } from 'vscode-debugadapter-testsupport'
55
import { DebugProtocol } from 'vscode-debugprotocol'
66
import * as semver from 'semver'
7+
import * as net from 'net'
78
chai.use(chaiAsPromised)
89
const assert = chai.assert
910

@@ -686,4 +687,21 @@ describe('PHP Debug Adapter', () => {
686687
await client.assertOutput('stderr', 'stderr output 1\nstderr output 2')
687688
})
688689
})
690+
691+
describe('special adapter tests', () => {
692+
it('max connections', async () => {
693+
await Promise.all([client.launch({ maxConnections: 1, log: true }), client.configurationSequence()])
694+
695+
let s1 = net.createConnection({ port: 9003 })
696+
await client.assertOutput('console', 'new connection 1 from ')
697+
net.createConnection({ port: 9003 })
698+
let o = await client.waitForEvent('output')
699+
assert.match(
700+
o.body!.output,
701+
/^new connection from .* - dropping due to max connection limit/,
702+
'Second connection does not generate proper error output'
703+
)
704+
s1.destroy()
705+
})
706+
})
689707
})

src/xdebugConnection.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,7 @@ export class Connection extends DbgpConnection {
784784
}
785785
}
786786
})
787+
this.on('close', () => this._initPromiseRejectFn(new Error('connection closed')))
787788
}
788789

789790
/** Returns a promise that gets resolved once the init packet arrives */

0 commit comments

Comments
 (0)