Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 28 additions & 67 deletions vpython/no_notebook.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,13 @@
import copy
import socket
import multiprocessing
import time


import signal
from urllib.parse import unquote

from .rate_control import rate

makeDaemonic = (platform.system() == "Windows")

# Redefine `Thread.run` to not show a traceback for Spyder when stopping
# the server by raising a KeyboardInterrupt or SystemExit.
Expand All @@ -39,8 +38,7 @@ def run(*args, **kwargs):
try:
run_old(*args, **kwargs)
except (KeyboardInterrupt, SystemExit):
pass
# ("VPython server stopped.")
print("VPython server stopped.")
except:
raise
threading.Thread.run = run
Expand All @@ -51,25 +49,22 @@ def run(*args, **kwargs):

# Check for Ctrl+C. SIGINT will also be sent by our code if WServer is closed.
def signal_handler(signal, frame):
#print("in signal handler, calling stop server")
stop_server()


signal.signal(signal.SIGINT, signal_handler)

# Requests from client to http server can be the following:
# get glowcomm.html, library .js files, images, or font files


def find_free_port():
def find_free_port(port):
s = socket.socket()
s.bind(('', 0)) # find an available port
s.bind(('', port))
return s.getsockname()[1]

if "VPYTHON_HTTP_PORT" in os.environ:
__HTTP_PORT = int(os.environ["VPYTHON_HTTP_PORT"])
else:
__HTTP_PORT = find_free_port()
__SOCKET_PORT = find_free_port()
__HTTP_PORT = find_free_port(4200)
__SOCKET_PORT = find_free_port(4201)

try:
if platform.python_implementation() == 'PyPy':
Expand All @@ -78,17 +73,17 @@ def find_free_port():
except:
pass

# try: # machinery for reusing ports
# fd = open('free_ports')
# __HTTP_PORT = int(fd.readline())
# __SOCKET_PORT = int(fd.readline())
# try: # machinery for reusing ports (2023/12/09 always use 4200 and 4201)
# fd = open('free_ports')
# __HTTP_PORT = int(fd.readline())
# __SOCKET_PORT = int(fd.readline())
# except:
# __HTTP_PORT = find_free_port()
# __SOCKET_PORT = find_free_port()
# fd = open('free_ports', 'w') # this writes to user program's directory
# fd.write(str(__HTTP_PORT))
# fd.write('\n')
# fd.write(str(__SOCKET_PORT))
# __HTTP_PORT = find_free_port()
# __SOCKET_PORT = find_free_port()
# fd = open('free_ports', 'w') # this writes to user program's directory
# fd.write(str(__HTTP_PORT))
# fd.write('\n')
# fd.write(str(__SOCKET_PORT))

# Make it possible for glowcomm.html to find out what the websocket port is:
js = __file__.replace(
Expand Down Expand Up @@ -215,18 +210,8 @@ async def onMessage(self, data, isBinary):
# message format used by notebook
msg = {'content': {'data': [m]}}
loop = asyncio.get_event_loop()
try:
await loop.run_in_executor(None, GW.handle_msg, msg)
except:
#
# this will throw a runtime exception after the main Thread
# has stopped, but we don't really case since the main thread
# is no longer there to do anything anyway.
if threading.main_thread().is_alive():
raise
else:
pass

await loop.run_in_executor(None, GW.handle_msg, msg)

def onClose(self, wasClean, code, reason):
"""Called when browser tab is closed."""
global websocketserving
Expand Down Expand Up @@ -261,24 +246,19 @@ def onClose(self, wasClean, code, reason):


try:
no_launch = os.environ.get("VPYTHON_NO_LAUNCH_BROWSER", False)
if no_launch=="0":
no_launch=False
if platform.python_implementation() == 'PyPy':
server_address = ('', 0) # let HTTPServer choose a free port
__server = HTTPServer(server_address, serveHTTP)
port = __server.server_port # get the chosen port
# Change the global variable to store the actual port used
__HTTP_PORT = port
if not no_launch:
_webbrowser.open('http://localhost:{}'.format(port)
_webbrowser.open('http://localhost:{}'.format(port)
) # or webbrowser.open_new_tab()
else:
__server = HTTPServer(('', __HTTP_PORT), serveHTTP)
# or webbrowser.open_new_tab()
if not no_launch:
if _browsertype == 'default': # uses default browser
_webbrowser.open('http://localhost:{}'.format(__HTTP_PORT))
if _browsertype == 'default': # uses default browser
_webbrowser.open('http://localhost:{}'.format(__HTTP_PORT))

except:
pass
Expand Down Expand Up @@ -312,7 +292,7 @@ def start_Qapp(port):
__m = multiprocessing.Process(target=start_Qapp, args=(__HTTP_PORT,))
__m.start()

__w = threading.Thread(target=__server.serve_forever, daemon=makeDaemonic)
__w = threading.Thread(target=__server.serve_forever)
__w.start()


Expand Down Expand Up @@ -345,16 +325,14 @@ def start_websocket_server():
# Put the websocket server in a separate thread running its own event loop.
# That works even if some other program (e.g. spyder) already running an
# async event loop.
__t = threading.Thread(target=start_websocket_server, daemon=makeDaemonic)
__t = threading.Thread(target=start_websocket_server)
__t.start()


def stop_server():
"""Shuts down all threads and exits cleanly."""
#print("in stop server")
global __server
__server.shutdown()

event_loop = txaio.config.loop
event_loop.stop()
# We've told the event loop to stop, but it won't shut down until we poke
Expand All @@ -373,36 +351,19 @@ def stop_server():
raise KeyboardInterrupt

if threading.main_thread().is_alive():
#print("main is alive...")
sys.exit(0)
else:
#
# check to see if the event loop is still going, if so join it.
#
#print("main is dead..")
if __t.is_alive():
#print("__t is alive still")
if threading.get_ident() != __t.ident:
#print("but it's not my thread, so I'll join...")
__t.join()
else:
#print("__t is alive, but that's my thread! So skip it.")
pass
else:
if makeDaemonic:
sys.exit(0)

pass
# If the main thread has already stopped, the python interpreter
# is likely just running .join on the two remaining threads (in
# python/threading.py:_shutdown). Since we just stopped those threads,
# we'll now exit.



GW = GlowWidget()

while not (httpserving and websocketserving): # try to make sure setup is complete
time.sleep(0.1)

rate(60)

# Dummy variable to import
_ = None