20
20
21
21
22
22
class ClientStatus (Enum ):
23
+ STARTING = auto () # thread started
23
24
CONNECTING = auto () # socket connecting
24
25
CONNECTED = auto () # socket connected, logging in
25
26
ONLINE = auto () # logged in, thread started
@@ -68,7 +69,7 @@ def _in_status(self, status: Union[ClientStatus, Collection[ClientStatus]]):
68
69
69
70
def _assert_status (self , status : Union [ClientStatus , Collection [ClientStatus ]]):
70
71
if not self ._in_status (status ):
71
- raise AssertionError ('Excepted status {} but {} found' .format (set ( status ) , self .__status ))
72
+ raise AssertionError ('Excepted status {} but {} found' .format (status , self .__status ))
72
73
73
74
def _is_connected (self ) -> bool :
74
75
return self ._in_status ({ClientStatus .CONNECTED , ClientStatus .ONLINE })
@@ -113,7 +114,7 @@ def __connect(self):
113
114
"""
114
115
status: STOPPED -> CONNECTED
115
116
"""
116
- self ._assert_status (ClientStatus .STOPPED )
117
+ self ._assert_status (ClientStatus .STARTING )
117
118
self ._set_status (ClientStatus .CONNECTING )
118
119
assert self .__server_address is not None
119
120
self .logger .info ('Connecting to {}' .format (self .__server_address ))
@@ -156,37 +157,26 @@ def _tick_connection(self):
156
157
# --------------
157
158
158
159
def start (self ):
159
- assert self ._on_external_thread ()
160
- if not self ._is_stopped ():
161
- self .logger .warning ('Client is running, cannot start again' )
162
- return
163
- acq = self .__start_stop_lock .acquire (blocking = False )
164
- if not acq :
165
- self .logger .warning ('Client is already starting' )
166
- return
167
- try :
168
- self .logger .debug ('Starting client' )
169
- self .__connection_done .clear ()
170
- super ().start ()
171
- self .__connection_done .wait ()
172
- finally :
173
- self .__start_stop_lock .release ()
160
+ self .logger .debug ('Starting client' )
161
+ with self .__start_stop_lock :
162
+ if not self ._is_stopped ():
163
+ self .logger .warning ('Client is running, cannot start again' )
164
+ return
165
+ self ._set_status (ClientStatus .STARTING )
166
+ self .__connection_done .clear ()
167
+ super ().start ()
168
+ self .__connection_done .wait ()
169
+ self .logger .debug ('Started client' )
174
170
175
171
def stop (self ):
176
- assert self ._on_external_thread ()
177
- if self ._is_stopped ():
178
- self .logger .warning ('Client is stopped, cannot stop again' )
179
- return
180
- acq = self .__start_stop_lock .acquire (blocking = False )
181
- if not acq :
182
- self .logger .warning ('Client is already stopping' )
183
- return
184
- try :
185
- self .logger .debug ('Stopping client' )
186
- self .__disconnect ()
187
- super ().stop ()
188
- finally :
189
- self .__start_stop_lock .release ()
172
+ self .logger .debug ('Stopping client' )
173
+ with self .__start_stop_lock :
174
+ if self ._is_stopped ():
175
+ self .logger .warning ('Client is stopped, cannot stop again' )
176
+ return
177
+ self .__disconnect () # state -> STOPPED or DISCONNECTED
178
+ super ().stop ()
179
+ self .logger .debug ('Stopped client' )
190
180
191
181
def restart (self ):
192
182
self .logger .info ('Restarting client' )
@@ -205,7 +195,7 @@ def _main_loop(self):
205
195
self ._connect_and_login ()
206
196
self ._set_status (ClientStatus .ONLINE )
207
197
except Exception as e :
208
- self .logger .error ('Failed to connect to {}: {}' .format (self .__server_address , e ))
198
+ ( self .logger .exception if self . logger . is_debug_enabled () else self . logger . error ) ('Failed to connect to {}: {}' .format (self .__server_address , e ))
209
199
self .__disconnect ()
210
200
self .__connection_done .set ()
211
201
else :
@@ -230,11 +220,14 @@ def _main_loop(self):
230
220
231
221
def _on_started (self ):
232
222
self .__connection_done .set ()
233
- self ._start_keep_alive_thread ()
223
+ self .__thread_keep_alive = self . _start_keep_alive_thread ()
234
224
235
225
def _on_stopped (self ):
236
226
if self ._is_connected ():
237
227
self .__disconnect ()
228
+ self .logger .debug ('Joining keep alive thread' )
229
+ self .__thread_keep_alive .join ()
230
+ self .logger .debug ('Joined keep alive thread' )
238
231
239
232
# ----------------
240
233
# Packet Logic
@@ -323,8 +316,8 @@ def reply_command(self, target: str, asker_payload: 'CommandPayload', result: Un
323
316
def _get_keep_alive_thread_name (cls ):
324
317
return 'KeepAlive'
325
318
326
- def _start_keep_alive_thread (self ):
327
- self ._start_thread (self ._keep_alive_loop , self ._get_keep_alive_thread_name ())
319
+ def _start_keep_alive_thread (self ) -> Thread :
320
+ return self ._start_thread (self ._keep_alive_loop , self ._get_keep_alive_thread_name ())
328
321
329
322
def _keep_alive_target (self ) -> str :
330
323
return constants .SERVER_NAME
0 commit comments