Skip to content

Commit 058ac92

Browse files
committed
Close Threads and HTTP Servers on window close
1 parent 49dfe9a commit 058ac92

File tree

5 files changed

+102
-34
lines changed

5 files changed

+102
-34
lines changed

src/main.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,9 @@ def install() -> None:
3131

3232
def main():
3333
logger.log("Main function started")
34-
3534
app_data, updater = setup()
36-
launcher_path: str = app_data.v_path("launcher")
37-
port, _ = host(launcher_path)
38-
39-
logger.log(f"Hosting Launcher on port: {port}")
40-
Launcher(f"http://localhost:{port}/", app_data, updater)
35+
36+
Launcher(app_data, updater)
4137
start()
4238

4339
if __name__ == '__main__':

src/utils/webhost.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Self, Callable
1+
from typing import Any, Self, Callable, TypeAlias
22

33
from os import chdir
44
from threading import Thread
@@ -9,6 +9,25 @@
99

1010
from utils.logger import logger
1111

12+
class ActiveServerData:
13+
server: HTTPServer | None
14+
thread: Thread | None
15+
16+
def __init__(self: Self) -> None:
17+
logger.log("Initializing ActiveServerData")
18+
self.server = None
19+
self.thread = None
20+
21+
def setServer(self: Self, server: HTTPServer) -> None:
22+
logger.log("Setting server in ActiveServerData")
23+
self.server = server
24+
25+
def setThread(self: Self, thread: Thread) -> None:
26+
logger.log("Setting thread in ActiveServerData")
27+
self.thread = thread
28+
29+
active_servers: dict[int, ActiveServerData] = {}
30+
1231
class SilentHandler(SimpleHTTPRequestHandler):
1332
def __init__(
1433
self: Self,
@@ -28,6 +47,8 @@ def host(path: str) -> tuple[int, Thread]:
2847
PORT: int = randint(49152, 65535)
2948
logger.log(f"Selected random port: {PORT}")
3049

50+
active_servers[PORT] = ActiveServerData()
51+
3152
def start_server(path: str, port: int) -> None:
3253
logger.log(f"Starting HTTP server on port: {port} with path: {path}")
3354

@@ -42,6 +63,7 @@ def start_server(path: str, port: int) -> None:
4263

4364
with HTTPServer(*server_args) as httpd:
4465
logger.log(f"HTTP server started on port: {port}")
66+
active_servers[port].setServer(httpd)
4567
httpd.serve_forever()
4668

4769
logger.log(f"Creating thread for HTTP server on port: {PORT}")
@@ -52,7 +74,26 @@ def start_server(path: str, port: int) -> None:
5274
)
5375

5476
logger.log(f"Starting thread for HTTP server on port: {PORT}")
77+
active_servers[PORT].setThread(thread)
5578
thread.start()
5679

5780
return PORT, thread
5881

82+
def close_server(port: int) -> None:
83+
logger.log(f"Closing server on port: {port}")
84+
if port not in active_servers:
85+
logger.log(f"No active server found on port: {port}")
86+
return
87+
88+
server_data = active_servers[port]
89+
if server_data.server:
90+
server_data.server.shutdown()
91+
logger.log(f"Server on port {port} has been shut down")
92+
93+
if server_data.thread:
94+
server_data.thread.join()
95+
logger.log(f"Thread for port {port} has been joined")
96+
97+
del active_servers[port]
98+
logger.log(f"Removed active server data for port: {port}")
99+

src/windows/console.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,38 @@
22

33
from utils.updater import Updater
44
from utils.shellhost import ShellProcess
5-
from utils.appdata import APP_DIR
5+
from utils.appdata import AppData, APP_DIR
6+
from utils.webhost import host, close_server
67
from utils.logger import logger
78

89
from windows.base import Base
910

1011
from sys import executable
1112

1213
class Console(Base):
14+
app_data: AppData
1315
updater: Updater
16+
port: int
1417
shell: ShellProcess
1518
filepath: str
1619

1720
def __init__(
1821
self: Self,
19-
url: str,
2022
filepath: str,
23+
app_data: AppData,
2124
) -> None:
2225
logger.log(f'Initializing console for file: {filepath}')
26+
27+
self.app_data = app_data
28+
29+
console_path: str = app_data.v_path("console")
30+
port, _ = host(console_path)
31+
32+
self.port = port
33+
url: str = f"http://localhost:{port}/"
34+
35+
logger.log(f'Hosting console at port: {port}')
36+
2337
super().__init__(
2438
url=url,
2539
title="GraphScript Launcher",
@@ -33,6 +47,10 @@ def __init__(
3347
def close(self: Self) -> None:
3448
logger.log(f'Closing console for file: {self.filepath}')
3549
if self.shell: self.shell.terminate()
50+
51+
logger.log('Closing console server')
52+
close_server(self.port)
53+
3654
super().close()
3755

3856
def add_console_output(self: Self, message: str) -> None:

src/windows/editor.py

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import Self
22

33
from utils.appdata import AppData
4-
from utils.webhost import host
4+
from utils.webhost import host, close_server
55
from utils.logger import logger
66

77
from windows.base import Base
@@ -15,22 +15,38 @@
1515
class Editor(Base):
1616
project_id: str
1717
app_data: AppData
18+
port: int
1819

1920
def __init__(
2021
self: Self,
21-
url: str,
2222
project_id: str,
2323
app_data: AppData,
2424
):
2525
logger.log(f'Initializing editor for project ID: {project_id}')
26+
2627
self.project_id = project_id
2728
self.app_data = app_data
2829

30+
editor_path: str = self.app_data.v_path("editor")
31+
port, _ = host(editor_path)
32+
33+
self.port = port
34+
url: str = f"http://localhost:{port}/"
35+
36+
logger.log(f'Hosting editor at port: {port}')
37+
2938
super().__init__(
3039
url=url,
3140
title='GraphScript',
3241
)
3342

43+
def close(self: Self) -> None:
44+
logger.log('Closing editor server')
45+
close_server(self.port)
46+
47+
logger.log(f'Closing editor for project ID: {self.project_id}')
48+
super().close()
49+
3450
def save_file(
3551
self: Self,
3652
content: str,
@@ -106,19 +122,12 @@ def restore_project(
106122
def run_project(self: Self, script: str) -> None:
107123
logger.log(f'Running project with ID: {self.project_id}')
108124

109-
console_path: str = self.app_data.v_path("console")
110125
script_path: str = f"projects/pr_{self.project_id}/console/entry.gsam"
111-
port, _ = host(console_path)
112-
113-
logger.log(f'Hosting console at port: {port}')
114-
self.app_data.store_data(
115-
script_path,
116-
script,
117-
)
126+
self.app_data.store_data(script_path, script)
118127

119128
logger.log(f'Launching console for script: {script_path}')
120129
Console(
121-
f"http://localhost:{port}/",
122130
f"{self.app_data.datapath}/data/{script_path}",
131+
self.app_data,
123132
)
124133

src/windows/launcher.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from utils.appdata import AppData
44
from utils.updater import Updater
5-
from utils.webhost import host
5+
from utils.webhost import host, close_server
66
from utils.logger import logger
77

88
from windows.base import Base
@@ -13,10 +13,10 @@
1313
class Launcher(Base):
1414
app_data: AppData
1515
updater: Updater
16+
port: int
1617

1718
def __init__(
1819
self: Self,
19-
url: str,
2020
app_data: AppData,
2121
updater: Updater
2222
) -> None:
@@ -25,13 +25,28 @@ def __init__(
2525
self.app_data = app_data
2626
self.updater = updater
2727

28+
launcher_path: str = app_data.v_path("launcher")
29+
port, _ = host(launcher_path)
30+
31+
self.port = port
32+
url: str = f"http://localhost:{port}/"
33+
34+
logger.log(f"Hosting Launcher on port: {port}")
35+
2836
super().__init__(
2937
url=url,
3038
title="GraphScript Launcher",
3139
dims=(800, 600),
3240
resizable=False,
3341
)
3442

43+
def close(self: Self) -> None:
44+
logger.log('Closing Launcher server')
45+
close_server(self.port)
46+
47+
logger.log('Closing Launcher window')
48+
super().close()
49+
3550
def get_data(self: Self) -> str:
3651
logger.log('Fetching launcher data')
3752
return self.app_data.fetch_data("launcher.json") or ""
@@ -42,18 +57,7 @@ def store_data(self: Self, data: str) -> bool:
4257

4358
def open_project(self: Self, project_id: str) -> None:
4459
logger.log(f'Opening project with ID: {project_id}')
45-
46-
editor_path: str = self.app_data.v_path("editor")
47-
port, _ = host(editor_path)
48-
49-
logger.log(f'Hosting editor at port: {port}')
50-
logger.log(f'Opening editor for project ID: {project_id}')
51-
52-
Editor(
53-
f"http://localhost:{port}/",
54-
project_id,
55-
self.app_data,
56-
)
60+
Editor(project_id, self.app_data)
5761

5862
self.close()
5963

0 commit comments

Comments
 (0)