1010from .compiler import (get_file_name , get_tmp_directory , get_tmp_hash_seed )
1111
1212import debugpy
13+ import time
1314
1415class DebugpyMessageQueue :
1516
@@ -96,13 +97,19 @@ class DebugpyClient:
9697 def __init__ (self , log , debugpy_stream , event_callback ):
9798 self .log = log
9899 self .debugpy_stream = debugpy_stream
99- self .routing_id = None
100100 self .event_callback = event_callback
101101 self .message_queue = DebugpyMessageQueue (self ._forward_event , self .log )
102+ self .debugpy_host = '127.0.0.1'
103+ self .debugpy_port = - 1
104+ self .routing_id = None
102105 self .wait_for_attach = True
103106 self .init_event = Event ()
104107 self .init_event_seq = - 1
105108
109+ def _get_endpoint (self ):
110+ host , port = self .get_host_port ()
111+ return 'tcp://' + host + ':' + str (port )
112+
106113 def _forward_event (self , msg ):
107114 if msg ['event' ] == 'initialized' :
108115 self .init_event .set ()
@@ -146,6 +153,28 @@ async def _handle_init_sequence(self):
146153 attach_rep = await self ._wait_for_response ()
147154 return attach_rep
148155
156+ def get_host_port (self ):
157+ if self .debugpy_port == - 1 :
158+ socket = self .debugpy_stream .socket
159+ socket .bind_to_random_port ('tcp://' + self .debugpy_host )
160+ self .endpoint = socket .getsockopt (zmq .LAST_ENDPOINT ).decode ('utf-8' )
161+ socket .unbind (self .endpoint )
162+ index = self .endpoint .rfind (':' )
163+ self .debugpy_port = self .endpoint [index + 1 :]
164+ return self .debugpy_host , self .debugpy_port
165+
166+
167+ def connect_tcp_socket (self ):
168+ self .debugpy_stream .socket .connect (self ._get_endpoint ())
169+ self .routing_id = self .debugpy_stream .socket .getsockopt (zmq .ROUTING_ID )
170+
171+ def disconnect_tcp_socket (self ):
172+ self .debugpy_stream .socket .disconnect (self ._get_endpoint ())
173+ self .routing_id = None
174+ self .init_event = Event ()
175+ self .init_event_seq = - 1
176+ self .wait_for_attach = True
177+
149178 def receive_dap_frame (self , frame ):
150179 self .message_queue .put_tcp_frame (frame )
151180
@@ -194,8 +223,11 @@ def __init__(self, log, debugpy_stream, event_callback, shell_socket, session):
194223 self .breakpoint_list = {}
195224 self .stopped_threads = []
196225
226+ self .debugpy_initialized = False
227+
197228 self .debugpy_host = '127.0.0.1'
198229 self .debugpy_port = 0
230+ self .endpoint = None
199231
200232 async def _forward_message (self , msg ):
201233 return await self .debugpy_client .send_dap_request (msg )
@@ -205,29 +237,24 @@ def tcp_client(self):
205237 return self .debugpy_client
206238
207239 def start (self ):
208- socket = self .debugpy_client .debugpy_stream .socket
209- socket .bind_to_random_port ('tcp://' + self .debugpy_host )
210- endpoint = socket .getsockopt (zmq .LAST_ENDPOINT ).decode ('utf-8' )
211- socket .unbind (endpoint )
212- index = endpoint .rfind (':' )
213- self .debugpy_port = endpoint [index + 1 :]
214- code = 'import debugpy;'
215- code += 'debugpy.listen(("' + self .debugpy_host + '",' + self .debugpy_port + '))'
216- content = {
217- 'code' : code ,
218- 'silent' : True
219- }
220- self .session .send (self .shell_socket , 'execute_request' , content ,
221- None , (self .shell_socket .getsockopt (zmq .ROUTING_ID )))
240+ if not self .debugpy_initialized :
241+ host , port = self .debugpy_client .get_host_port ()
242+ code = 'import debugpy;'
243+ code += 'debugpy.listen(("' + host + '",' + port + '))'
244+ content = {
245+ 'code' : code ,
246+ 'silent' : True
247+ }
248+ self .session .send (self .shell_socket , 'execute_request' , content ,
249+ None , (self .shell_socket .getsockopt (zmq .ROUTING_ID )))
222250
223- self .session .recv (self .shell_socket , mode = 0 )
224- socket . connect ( endpoint )
225- debugpy . trace_this_thread ( False )
226- return True
251+ ident , msg = self .session .recv (self .shell_socket , mode = 0 )
252+ self . debugpy_initialized = msg [ 'content' ][ 'status' ] == 'ok'
253+ self . debugpy_client . connect_tcp_socket ( )
254+ return self . debugpy_initialized
227255
228256 def stop (self ):
229- # TODO
230- pass
257+ self .debugpy_client .disconnect_tcp_socket ()
231258
232259 async def dumpCell (self , message ):
233260 code = message ['arguments' ]['code' ]
@@ -289,9 +316,10 @@ async def variables(self, message):
289316 return reply
290317
291318 async def attach (self , message ):
319+ host , port = self .debugpy_client .get_host_port ()
292320 message ['arguments' ]['connect' ] = {
293- 'host' : self . debugpy_host ,
294- 'port' : self . debugpy_port
321+ 'host' : host ,
322+ 'port' : port
295323 }
296324 message ['arguments' ]['logToFile' ] = True
297325 return await self ._forward_message (message )
0 commit comments