1313import threading
1414from pathlib import Path
1515import socket
16+ import urllib .request
17+ import urllib .error
18+
19+ # Single instance lock port
20+ SINGLE_INSTANCE_PORT = 58765
1621
1722def setup_environment ():
1823 """Set up the macOS app environment."""
@@ -60,18 +65,31 @@ def setup_environment():
6065
6166def check_single_instance ():
6267 """Check if another instance of the app is already running."""
63- lock_file = Path .home () / "Library" / "Application Support" / "HeartMuLa" / ".lock"
64- lock_file .parent .mkdir (parents = True , exist_ok = True )
65-
6668 # Try to bind to a port to ensure single instance
6769 try :
6870 sock = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
69- sock .bind (('127.0.0.1' , 58765 )) # Random high port for lock
71+ sock .bind (('127.0.0.1' , SINGLE_INSTANCE_PORT ))
7072 return sock # Keep socket open to maintain lock
7173 except OSError :
7274 # Port is already in use - another instance is running
7375 return None
7476
77+ def wait_for_server (url = 'http://127.0.0.1:8000/health' , timeout = 30 ):
78+ """Wait for the server to be ready by polling the health endpoint."""
79+ print ("Waiting for server to start..." )
80+ start_time = time .time ()
81+ while time .time () - start_time < timeout :
82+ try :
83+ response = urllib .request .urlopen (url , timeout = 1 )
84+ if response .getcode () == 200 :
85+ print ("Server is ready!" )
86+ return True
87+ except (urllib .error .URLError , ConnectionError , OSError ):
88+ # Server not ready yet, wait a bit
89+ time .sleep (0.5 )
90+ print (f"Warning: Server did not respond within { timeout } seconds" )
91+ return False
92+
7593def launch_server (app_dir , logs_dir ):
7694 """Launch the FastAPI server."""
7795 # Import and run the FastAPI app
@@ -98,16 +116,15 @@ def run_server():
98116 server_thread .start ()
99117
100118 # Wait for server to be ready
101- print ("Waiting for server to start..." )
102- time .sleep (3 )
119+ wait_for_server ()
103120
104121 # Launch pywebview window
105122 try :
106123 import webview
107124 print ("Opening HeartMuLa Studio window..." )
108125
109126 # Create window with custom settings
110- window = webview .create_window (
127+ webview .create_window (
111128 'HeartMuLa Studio' ,
112129 'http://127.0.0.1:8000' ,
113130 width = 1400 ,
@@ -125,7 +142,15 @@ def run_server():
125142 except ImportError :
126143 print ("Warning: pywebview not available, falling back to browser" )
127144 import webbrowser
128- webbrowser .open ("http://localhost:8000" )
145+ webbrowser .open ("http://127.0.0.1:8000" )
146+ # Keep the server running
147+ while True :
148+ time .sleep (1 )
149+ except Exception as e :
150+ print (f"Error launching window: { e } " )
151+ print ("Falling back to browser..." )
152+ import webbrowser
153+ webbrowser .open ("http://127.0.0.1:8000" )
129154 # Keep the server running
130155 while True :
131156 time .sleep (1 )
0 commit comments