Skip to content
This repository was archived by the owner on Aug 28, 2020. It is now read-only.

Commit d0aaebf

Browse files
committed
Merge pull request #91 from robertbasic/feature/debug-all-requests
Feature/debug all requests. Resolves #86
2 parents be5e6af + b55321a commit d0aaebf

File tree

3 files changed

+282
-234
lines changed

3 files changed

+282
-234
lines changed

pugdebug/debugger.py

Lines changed: 125 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,26 @@
99

1010
__author__ = "robertbasic"
1111

12+
from collections import deque
1213
from PyQt5.QtCore import QObject, pyqtSignal
1314

1415
from pugdebug.server import PugdebugServer
1516

1617

1718
class PugdebugDebugger(QObject):
19+
1820
server = None
1921

22+
connections = deque()
23+
current_connection = None
24+
2025
init_message = None
2126
step_result = ''
2227

2328
current_file = ''
2429
current_line = 0
2530

2631
debugging_started_signal = pyqtSignal()
27-
debugging_cancelled_signal = pyqtSignal()
2832
debugging_stopped_signal = pyqtSignal()
2933
step_command_signal = pyqtSignal()
3034
got_all_variables_signal = pyqtSignal(object)
@@ -39,67 +43,111 @@ class PugdebugDebugger(QObject):
3943
def __init__(self):
4044
"""Init the debugger object
4145
42-
Create a PugdebugServer object used to communicate with xdebug client
43-
through TCP.
46+
Create a PugdebugServer objects that listens to new connections
47+
from xdebug.
4448
45-
Connect signals to slots.
49+
Connect server signals to slots.
4650
"""
4751
super(PugdebugDebugger, self).__init__()
4852

4953
self.server = PugdebugServer()
5054

55+
self.connect_server_signals()
56+
57+
def connect_server_signals(self):
58+
"""Connect server signals to slots
59+
"""
5160
self.server.server_connected_signal.connect(
5261
self.handle_server_connected
5362
)
54-
self.server.server_cancelled_signal.connect(
55-
self.handle_server_cancelled
63+
self.server.server_stopped_signal.connect(
64+
self.handle_server_stopped
65+
)
66+
67+
def connect_connection_signals(self, connection):
68+
"""Connect signals for a new connection
69+
70+
Connect signals that gets emitted when a connection is stopped
71+
or detached, when a step command is done, when variables are read,
72+
when stacktraces are read, when breakpoints are set or removed,
73+
when breakpoints are read, when expressions are evaluated.
74+
"""
75+
76+
# Stop/detach signals
77+
connection.server_stopped_signal.connect(
78+
self.handle_server_stopped
79+
)
80+
connection.server_detached_signal.connect(
81+
self.handle_server_stopped
5682
)
57-
self.server.server_stopped_signal.connect(self.handle_server_stopped)
58-
self.server.server_detached_signal.connect(
59-
self.handle_server_detached
83+
84+
# Step command signals
85+
connection.server_stepped_signal.connect(
86+
self.handle_server_stepped
6087
)
61-
self.server.server_stepped_signal.connect(self.handle_server_stepped)
62-
self.server.server_got_variables_signal.connect(
88+
89+
# Variables signals
90+
connection.server_got_variables_signal.connect(
6391
self.handle_server_got_variables
6492
)
65-
self.server.server_got_stacktraces_signal.connect(
93+
94+
# Stacktraces signals
95+
connection.server_got_stacktraces_signal.connect(
6696
self.handle_server_got_stacktraces
6797
)
68-
self.server.server_set_init_breakpoints_signal.connect(
98+
99+
# Breakpoints signals
100+
connection.server_set_init_breakpoints_signal.connect(
69101
self.handle_server_set_breakpoint
70102
)
71-
self.server.server_set_breakpoint_signal.connect(
103+
connection.server_set_breakpoint_signal.connect(
72104
self.handle_server_set_breakpoint
73105
)
74-
self.server.server_removed_breakpoint_signal.connect(
106+
connection.server_removed_breakpoint_signal.connect(
75107
self.handle_server_removed_breakpoint
76108
)
77-
self.server.server_listed_breakpoints_signal.connect(
109+
connection.server_listed_breakpoints_signal.connect(
78110
self.handle_server_listed_breakpoints
79111
)
80112

81-
self.server.server_expression_evaluated_signal.connect(
113+
# Expressions signals
114+
connection.server_expression_evaluated_signal.connect(
82115
self.handle_server_expression_evaluated
83116
)
84-
self.server.server_expressions_evaluated_signal.connect(
117+
connection.server_expressions_evaluated_signal.connect(
85118
self.handle_server_expressions_evaluated
86119
)
87120

88121
def cleanup(self):
89122
"""Cleanup debugger when it's done
123+
124+
If there is an active connection, disconnect from it and clear
125+
all the remaining connections.
126+
127+
Stop the server from listening.
128+
129+
Clean up attributes.
90130
"""
91-
if self.server.is_connected():
92-
self.server.disconnect()
131+
if self.is_connected():
132+
self.current_connection.disconnect()
133+
self.connections.clear()
134+
135+
self.server.stop()
93136

137+
self.current_connection = None
94138
self.step_result = ''
95139
self.current_file = ''
96140
self.current_line = 0
97141

98142
def is_connected(self):
99-
return self.server.is_connected()
143+
"""Is there an active connection
144+
"""
145+
return self.current_connection is not None
100146

101-
def is_waiting_for_connection(self):
102-
return self.server.is_waiting_for_connection()
147+
def has_pending_connections(self):
148+
"""Are there any pending connections?
149+
"""
150+
return len(self.connections) > 0
103151

104152
def start_debug(self):
105153
"""Start a debugging session
@@ -108,61 +156,77 @@ def start_debug(self):
108156
"""
109157
self.server.connect()
110158

111-
def handle_server_connected(self, init_message):
112-
"""Handle when server gets connected
159+
def handle_server_connected(self, connection):
160+
"""Handle when the server establishes a new connection
161+
162+
Connect the signals for the new connection.
163+
164+
Add it to the queue of connections.
113165
114-
Emit a debugging started signal.
166+
If there is no active connection, start the new connection.
115167
"""
116-
if 'error' not in init_message:
117-
self.init_message = init_message
168+
self.connect_connection_signals(connection)
118169

119-
self.debugging_started_signal.emit()
120-
else:
121-
self.error_signal.emit(init_message['error'])
170+
self.connections.append(connection)
122171

123-
def cancel_debug(self):
124-
self.server.cancel()
172+
if not self.is_connected():
173+
self.start_new_connection()
125174

126-
def handle_server_cancelled(self):
127-
self.debugging_cancelled_signal.emit()
175+
def start_new_connection(self):
176+
"""Start a new connection
128177
129-
def stop_debug(self):
130-
"""Stop a debugging session
178+
Get the first (oldest) connection from the queue, set it's init
179+
message as the init message for the session, set it as the current
180+
connection and emit the debugging started signal.
131181
"""
132-
self.server.stop()
182+
connection = self.connections.popleft()
183+
self.init_message = connection.init_message
184+
self.current_connection = connection
133185

134-
def handle_server_stopped(self):
135-
"""Handle when server gets disconnected
186+
self.debugging_started_signal.emit()
136187

137-
Emit a debugging stopped signal.
188+
def stop_debug(self):
189+
"""Stop a debugging session
190+
191+
If there is an active connection, stop only that one, otherwise
192+
stop the server from listening to new connections.
138193
"""
139-
self.debugging_stopped_signal.emit()
194+
if self.is_connected():
195+
self.current_connection.stop()
196+
else:
197+
self.server.stop()
140198

141199
def detach_debug(self):
142-
"""Detach a debugging session
200+
"""Detach the current connection
143201
"""
144-
self.server.detach()
202+
if self.is_connected():
203+
self.current_connection.detach()
145204

146-
def handle_server_detached(self):
147-
"""Handle when server gets ditached
205+
def handle_server_stopped(self):
206+
"""Handle when a server stopped signal is received
207+
208+
If there are pending connections, start a new one.
148209
149-
Emit a debugging stopped signal, as the
150-
debugger should behave the same like when
151-
a debugging session is stopped.
210+
Otherwise clean up and emit a server stopped signal.
152211
"""
153-
self.debugging_stopped_signal.emit()
212+
if self.has_pending_connections():
213+
self.start_new_connection()
214+
else:
215+
self.cleanup()
216+
217+
self.debugging_stopped_signal.emit()
154218

155219
def run_debug(self):
156-
self.server.step_run()
220+
self.current_connection.step_run()
157221

158222
def step_over(self):
159-
self.server.step_over()
223+
self.current_connection.step_over()
160224

161225
def step_into(self):
162-
self.server.step_into()
226+
self.current_connection.step_into()
163227

164228
def step_out(self):
165-
self.server.step_out()
229+
self.current_connection.step_out()
166230

167231
def handle_server_stepped(self, step_result):
168232
"""Handle when server executes a step command
@@ -174,7 +238,7 @@ def handle_server_stepped(self, step_result):
174238
self.step_command_signal.emit()
175239

176240
def post_step_command(self, post_step_data):
177-
self.server.post_step_command(post_step_data)
241+
self.current_connection.post_step_command(post_step_data)
178242

179243
def handle_server_got_variables(self, variables):
180244
"""Handle when server recieves all variables
@@ -191,23 +255,23 @@ def handle_server_got_stacktraces(self, stacktraces):
191255
self.got_stacktraces_signal.emit(stacktraces)
192256

193257
def set_init_breakpoints(self, breakpoints):
194-
self.server.set_init_breakpoints(breakpoints)
258+
self.current_connection.set_init_breakpoints(breakpoints)
195259

196260
def set_breakpoint(self, breakpoint):
197-
self.server.set_breakpoint(breakpoint)
261+
self.current_connection.set_breakpoint(breakpoint)
198262

199263
def handle_server_set_breakpoint(self, successful):
200264
if successful:
201265
self.list_breakpoints()
202266

203267
def remove_breakpoint(self, breakpoint_id):
204-
self.server.remove_breakpoint(breakpoint_id)
268+
self.current_connection.remove_breakpoint(breakpoint_id)
205269

206270
def handle_server_removed_breakpoint(self, breakpoint_id):
207271
self.breakpoint_removed_signal.emit(breakpoint_id)
208272

209273
def list_breakpoints(self):
210-
self.server.list_breakpoints()
274+
self.current_connection.list_breakpoints()
211275

212276
def handle_server_listed_breakpoints(self, breakpoints):
213277
self.breakpoints_listed_signal.emit(breakpoints)
@@ -220,11 +284,11 @@ def get_index_file(self):
220284

221285
def evaluate_expression(self, index, expression):
222286
"""Evaluates a single expression"""
223-
self.server.evaluate_expression(index, expression)
287+
self.current_connection.evaluate_expression(index, expression)
224288

225289
def evaluate_expressions(self, expressions):
226290
"""Evaluates a list of expressions"""
227-
self.server.evaluate_expressions(expressions)
291+
self.current_connection.evaluate_expressions(expressions)
228292

229293
def handle_server_expression_evaluated(self, index, result):
230294
"""Handle when server evaluates an expression"""

0 commit comments

Comments
 (0)