Skip to content

Commit

Permalink
Fix microsoft#1713: Adapter: multiple concurrent sessions
Browse files Browse the repository at this point in the history
  • Loading branch information
int19h committed Oct 28, 2019
1 parent 492e5e0 commit 48cee68
Show file tree
Hide file tree
Showing 18 changed files with 803 additions and 399 deletions.
13 changes: 11 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@

// For these, ptvsd.adapter must be started first via the above configuration.
{
//"debugServer": 8765,
"name": "Launch Python file [debugServer]",
"type": "python",
"request": "launch",
"debugServer": 8765,
//"console": "internalConsole",
"console": "integratedTerminal",
//"console": "externalTerminal",
Expand All @@ -30,12 +30,21 @@
//"ptvsdArgs": ["--log-stderr"],
},
{
//"debugServer": 8765,
"name": "Attach [debugServer]",
"type": "python",
"request": "attach",
"debugServer": 8765,
"host": "localhost",
"port": 5678,
},
{
//"debugServer": 8765,
"name": "Attach Child Process [debugServer]",
"type": "python",
"request": "attach",
"host": "localhost",
"port": 5678,
"subProcessId": 00000,
},
]
}
4 changes: 2 additions & 2 deletions src/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_defaults.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'''
This module holds the customization settings for the debugger.
'''
from _pydevd_bundle.pydevd_constants import QUOTED_LINE_PROTOCOL
from _pydevd_bundle.pydevd_constants import HTTP_JSON_PROTOCOL


class PydevdCustomization(object):
DEFAULT_PROTOCOL = QUOTED_LINE_PROTOCOL
DEFAULT_PROTOCOL = HTTP_JSON_PROTOCOL
49 changes: 25 additions & 24 deletions src/ptvsd/adapter/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

def main(args):
from ptvsd.common import log, options as common_options
from ptvsd.adapter import session, options as adapter_options
from ptvsd.adapter import ide, server, session, options as adapter_options

if args.log_stderr:
log.stderr.levels |= set(log.LEVELS)
Expand All @@ -30,30 +30,31 @@ def main(args):
log.to_file(prefix="ptvsd.adapter")
log.describe_environment("ptvsd.adapter startup environment:")

session = session.Session()
if args.for_enable_attach and args.port is None:
log.error("--for-enable-attach requires --port")
sys.exit(64)

server_host, server_port = server.listen()
ide_host, ide_port = ide.listen(port=args.port)

if args.for_enable_attach:
endpoints = {
"ide": {"host": ide_host, "port": ide_port},
"server": {"host": server_host, "port": server_port}
}
log.info("Sending endpoints to stdout: {0!r}", endpoints)
json.dump(endpoints, sys.stdout)
sys.stdout.write("\n")
sys.stdout.flush()

if args.port is None:
session.connect_to_ide()
else:
if args.for_enable_attach:
# Users may want the adapter to choose the port for them, by setting port==0.
# For example, the Python Data Science extension uses this mode in enable_attach.
# Let enable_attach know the port that users should use to connect to the adapter.
with session.accept_connection_from_ide((args.host, args.port)) as (adapter_host, adapter_port):
# This mode is used only for enable_attach. Here, we always connect to
# adapter from the debug server as client. Adapter needs to start a listener
# and provide that port to debug server.
with session.accept_connection_from_server() as (server_host, server_port):
connection_details = {
"adapter": {"host": adapter_host, "port": adapter_port},
"server": {"host": server_host, "port": server_port}
}
log.info("Writing to stdout for enable_attach: {0!r}", connection_details)
print(json.dumps(connection_details))
sys.stdout.flush()
else:
with session.accept_connection_from_ide((args.host, args.port)) as (_, adapter_port):
pass
session.wait_for_completion()
ide.IDE("stdio")

server.wait_until_disconnected()
log.info("All debug servers disconnected; waiting for remaining sessions...")

session.wait_until_ended()
log.info("All debug sessions have ended; exiting.")


def _parse_argv(argv):
Expand Down
26 changes: 18 additions & 8 deletions src/ptvsd/adapter/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,29 @@ class Component(util.Observable):
to wait_for() a change caused by another component.
"""

def __init__(self, session, stream):
def __init__(self, session, stream=None, channel=None):
assert (stream is None) ^ (channel is None)
super(Component, self).__init__()

self.session = session
stream.name = str(self)
self.channel = messaging.JsonMessageChannel(stream, self)
self.is_connected = True

self.observers += [lambda *_: session.notify_changed()]
self.channel.start()
with session:
# Hold the session lock to prevent message handlers from running while
# we're still initializing the session.
if channel is None:
stream.name = str(self)
channel = messaging.JsonMessageChannel(stream, self)
channel.start()
else:
channel.name = channel.stream.name = str(self)
channel.handlers = self

self.channel = channel
self.is_connected = True

self.observers += [lambda *_: session.notify_changed()]

def __str__(self):
return fmt("{0}-{1}", type(self).__name__, self.session.id)
return fmt("{0}[{1}]", type(self).__name__, self.session.id)

@property
def ide(self):
Expand Down
Loading

0 comments on commit 48cee68

Please sign in to comment.