14
14
import copy
15
15
import socket
16
16
import multiprocessing
17
- import time
17
+
18
18
19
19
import signal
20
20
from urllib .parse import unquote
21
21
22
22
from .rate_control import rate
23
23
24
- makeDaemonic = (platform .system () == "Windows" )
25
24
26
25
# Redefine `Thread.run` to not show a traceback for Spyder when stopping
27
26
# the server by raising a KeyboardInterrupt or SystemExit.
@@ -39,8 +38,7 @@ def run(*args, **kwargs):
39
38
try :
40
39
run_old (* args , ** kwargs )
41
40
except (KeyboardInterrupt , SystemExit ):
42
- pass
43
- # ("VPython server stopped.")
41
+ print ("VPython server stopped." )
44
42
except :
45
43
raise
46
44
threading .Thread .run = run
@@ -51,25 +49,22 @@ def run(*args, **kwargs):
51
49
52
50
# Check for Ctrl+C. SIGINT will also be sent by our code if WServer is closed.
53
51
def signal_handler (signal , frame ):
54
- #print("in signal handler, calling stop server")
55
52
stop_server ()
56
53
54
+
57
55
signal .signal (signal .SIGINT , signal_handler )
58
56
59
57
# Requests from client to http server can be the following:
60
58
# get glowcomm.html, library .js files, images, or font files
61
59
62
60
63
- def find_free_port ():
61
+ def find_free_port (port ):
64
62
s = socket .socket ()
65
- s .bind (('' , 0 )) # find an available port
63
+ s .bind (('' , port ))
66
64
return s .getsockname ()[1 ]
67
65
68
- if "VPYTHON_HTTP_PORT" in os .environ :
69
- __HTTP_PORT = int (os .environ ["VPYTHON_HTTP_PORT" ])
70
- else :
71
- __HTTP_PORT = find_free_port ()
72
- __SOCKET_PORT = find_free_port ()
66
+ __HTTP_PORT = find_free_port (4200 )
67
+ __SOCKET_PORT = find_free_port (4201 )
73
68
74
69
try :
75
70
if platform .python_implementation () == 'PyPy' :
@@ -78,17 +73,17 @@ def find_free_port():
78
73
except :
79
74
pass
80
75
81
- # try: # machinery for reusing ports
82
- # fd = open('free_ports')
83
- # __HTTP_PORT = int(fd.readline())
84
- # __SOCKET_PORT = int(fd.readline())
76
+ # try: # machinery for reusing ports (2023/12/09 always use 4200 and 4201)
77
+ # fd = open('free_ports')
78
+ # __HTTP_PORT = int(fd.readline())
79
+ # __SOCKET_PORT = int(fd.readline())
85
80
# except:
86
- # __HTTP_PORT = find_free_port()
87
- # __SOCKET_PORT = find_free_port()
88
- # fd = open('free_ports', 'w') # this writes to user program's directory
89
- # fd.write(str(__HTTP_PORT))
90
- # fd.write('\n')
91
- # fd.write(str(__SOCKET_PORT))
81
+ # __HTTP_PORT = find_free_port()
82
+ # __SOCKET_PORT = find_free_port()
83
+ # fd = open('free_ports', 'w') # this writes to user program's directory
84
+ # fd.write(str(__HTTP_PORT))
85
+ # fd.write('\n')
86
+ # fd.write(str(__SOCKET_PORT))
92
87
93
88
# Make it possible for glowcomm.html to find out what the websocket port is:
94
89
js = __file__ .replace (
@@ -215,18 +210,8 @@ async def onMessage(self, data, isBinary):
215
210
# message format used by notebook
216
211
msg = {'content' : {'data' : [m ]}}
217
212
loop = asyncio .get_event_loop ()
218
- try :
219
- await loop .run_in_executor (None , GW .handle_msg , msg )
220
- except :
221
- #
222
- # this will throw a runtime exception after the main Thread
223
- # has stopped, but we don't really case since the main thread
224
- # is no longer there to do anything anyway.
225
- if threading .main_thread ().is_alive ():
226
- raise
227
- else :
228
- pass
229
-
213
+ await loop .run_in_executor (None , GW .handle_msg , msg )
214
+
230
215
def onClose (self , wasClean , code , reason ):
231
216
"""Called when browser tab is closed."""
232
217
global websocketserving
@@ -261,24 +246,19 @@ def onClose(self, wasClean, code, reason):
261
246
262
247
263
248
try :
264
- no_launch = os .environ .get ("VPYTHON_NO_LAUNCH_BROWSER" , False )
265
- if no_launch == "0" :
266
- no_launch = False
267
249
if platform .python_implementation () == 'PyPy' :
268
250
server_address = ('' , 0 ) # let HTTPServer choose a free port
269
251
__server = HTTPServer (server_address , serveHTTP )
270
252
port = __server .server_port # get the chosen port
271
253
# Change the global variable to store the actual port used
272
254
__HTTP_PORT = port
273
- if not no_launch :
274
- _webbrowser .open ('http://localhost:{}' .format (port )
255
+ _webbrowser .open ('http://localhost:{}' .format (port )
275
256
) # or webbrowser.open_new_tab()
276
257
else :
277
258
__server = HTTPServer (('' , __HTTP_PORT ), serveHTTP )
278
259
# or webbrowser.open_new_tab()
279
- if not no_launch :
280
- if _browsertype == 'default' : # uses default browser
281
- _webbrowser .open ('http://localhost:{}' .format (__HTTP_PORT ))
260
+ if _browsertype == 'default' : # uses default browser
261
+ _webbrowser .open ('http://localhost:{}' .format (__HTTP_PORT ))
282
262
283
263
except :
284
264
pass
@@ -312,7 +292,7 @@ def start_Qapp(port):
312
292
__m = multiprocessing .Process (target = start_Qapp , args = (__HTTP_PORT ,))
313
293
__m .start ()
314
294
315
- __w = threading .Thread (target = __server .serve_forever , daemon = makeDaemonic )
295
+ __w = threading .Thread (target = __server .serve_forever )
316
296
__w .start ()
317
297
318
298
@@ -345,16 +325,14 @@ def start_websocket_server():
345
325
# Put the websocket server in a separate thread running its own event loop.
346
326
# That works even if some other program (e.g. spyder) already running an
347
327
# async event loop.
348
- __t = threading .Thread (target = start_websocket_server , daemon = makeDaemonic )
328
+ __t = threading .Thread (target = start_websocket_server )
349
329
__t .start ()
350
330
351
331
352
332
def stop_server ():
353
333
"""Shuts down all threads and exits cleanly."""
354
- #print("in stop server")
355
334
global __server
356
335
__server .shutdown ()
357
-
358
336
event_loop = txaio .config .loop
359
337
event_loop .stop ()
360
338
# We've told the event loop to stop, but it won't shut down until we poke
@@ -373,36 +351,19 @@ def stop_server():
373
351
raise KeyboardInterrupt
374
352
375
353
if threading .main_thread ().is_alive ():
376
- #print("main is alive...")
377
354
sys .exit (0 )
378
355
else :
379
- #
380
- # check to see if the event loop is still going, if so join it.
381
- #
382
- #print("main is dead..")
383
- if __t .is_alive ():
384
- #print("__t is alive still")
385
- if threading .get_ident () != __t .ident :
386
- #print("but it's not my thread, so I'll join...")
387
- __t .join ()
388
- else :
389
- #print("__t is alive, but that's my thread! So skip it.")
390
- pass
391
- else :
392
- if makeDaemonic :
393
- sys .exit (0 )
394
-
356
+ pass
395
357
# If the main thread has already stopped, the python interpreter
396
358
# is likely just running .join on the two remaining threads (in
397
359
# python/threading.py:_shutdown). Since we just stopped those threads,
398
360
# we'll now exit.
399
-
361
+
362
+
400
363
GW = GlowWidget ()
401
364
402
365
while not (httpserving and websocketserving ): # try to make sure setup is complete
403
- time .sleep (0.1 )
404
-
366
+ rate (60 )
405
367
406
368
# Dummy variable to import
407
369
_ = None
408
-
0 commit comments