-
Notifications
You must be signed in to change notification settings - Fork 1
/
dev.py
103 lines (77 loc) · 2.62 KB
/
dev.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import asyncio
import http.server
import socketserver
from threading import Timer
try:
import websockets
from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer
_have_dev_dependencies = True
except:
print("watchdog and/or websockets are not installed, no hot-reloading support")
_have_dev_dependencies = False
# Disable caching in HTTP server
class NoCacheHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
def end_headers(self):
self.send_header(
"Cache-Control", "no-store, no-cache, must-revalidate, max-age=0"
)
super().end_headers()
def run_http_server():
PORT = 8000
Handler = NoCacheHTTPRequestHandler
httpd = socketserver.TCPServer(("", PORT), Handler)
print(f"Serving HTTP on port {PORT}")
httpd.serve_forever()
clients = set()
async def websocket_handler(websocket, path):
clients.add(websocket)
try:
async for message in websocket:
pass
finally:
clients.remove(websocket)
async def notify_clients(message):
print(f"notify {len(clients)} clients", message)
if clients: # Send the message to all connected clients
for client in clients:
await client.send(message)
class FileChangeHandler(FileSystemEventHandler):
def __init__(self, loop):
self.loop = loop
self.debounce_timer = None
self.last_event = None
def _debounced_notify(self):
if self.last_event:
asyncio.run_coroutine_threadsafe(notify_clients("update"), self.loop)
def on_any_event(self, event):
if event.event_type != "closed":
return
self.last_event = event
if self.debounce_timer:
self.debounce_timer.cancel()
self.debounce_timer = Timer(0.1, self._debounced_notify)
self.debounce_timer.start()
def main():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
if _have_dev_dependencies:
websocket_server = websockets.serve(websocket_handler, "localhost", 6789)
loop.run_until_complete(websocket_server)
from threading import Thread
http_thread = Thread(target=run_http_server)
http_thread.start()
if _have_dev_dependencies:
event_handler = FileChangeHandler(loop)
observer = Observer()
observer.schedule(event_handler, path="webgpu", recursive=True)
observer.start()
try:
loop.run_forever()
except KeyboardInterrupt:
if _have_dev_dependencies:
observer.stop()
if _have_dev_dependencies:
observer.join()
if __name__ == "__main__":
main()