Skip to content

Commit a220dc5

Browse files
committed
refactor: improve ngrok management
- Remove duplicate ngrok startup logic from NgrokManager - Improve ngrok health check and URL retrieval - Add better error handling and logging - Update entrypoint script with better ngrok startup (cherry picked from commit b67079b86bbfa5e42819a0ca23b74144e263c3eb)
1 parent f300193 commit a220dc5

File tree

1 file changed

+36
-81
lines changed

1 file changed

+36
-81
lines changed

core/src/ngrok_manager.py

Lines changed: 36 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import os
2-
import subprocess
32
import time
43
import requests
54

65

76
class NgrokManager:
87
"""
9-
Class responsible for managing ngrok tunnels, including starting the tunnel,
8+
Class responsible for managing ngrok tunnels, including monitoring the tunnel,
109
uploading the URL to the gateway, and verifying the status of the ngrok connection.
1110
"""
1211

@@ -26,75 +25,53 @@ def refresh_environment_variables(self) -> None:
2625
def check_ngrok_health(self) -> bool:
2726
"""Basic health check to confirm ngrok's local API is reachable."""
2827
try:
29-
print(f"Performing health check on ngrok API: \
30-
{self.ngrok_api_url}")
28+
print(f"Checking ngrok API: {self.ngrok_api_url}")
3129
response = requests.get(self.ngrok_api_url, timeout=self.timeout)
32-
print(f"Health check response: {response.status_code}")
3330
return response.status_code == 200
3431
except requests.RequestException as e:
3532
print(f"ngrok health check failed: {e}")
3633
return False
3734

38-
def start_ngrok(self) -> str:
39-
"""Start ngrok in the background and verify its initialization."""
35+
def get_ngrok_url(self) -> str:
36+
"""Get the current ngrok URL."""
4037
try:
41-
print("Starting ngrok...")
42-
local_port = os.getenv("LOCAL_PORT", "5001")
43-
ngrok_command = f"ngrok http {local_port}"
44-
45-
# Start ngrok in the background without using a 'with' statement
46-
subprocess.Popen(
47-
ngrok_command.split(),
48-
stdout=subprocess.DEVNULL, # Suppress output
49-
stderr=subprocess.DEVNULL # Suppress error output
50-
)
51-
52-
# Allow ngrok some time to start
53-
retries = 5
54-
for attempt in range(retries):
55-
print(f"Attempt {attempt + 1} to check ngrok health...")
56-
time.sleep(2)
57-
if self.check_ngrok_health():
58-
response = requests.get(
59-
self.ngrok_api_url, timeout=self.timeout)
60-
tunnels = response.json().get('tunnels', [])
61-
for tunnel in tunnels:
62-
if tunnel.get('proto') == 'https':
63-
ngrok_url = tunnel['public_url']
64-
print(f"ngrok URL: {ngrok_url}")
65-
return ngrok_url
66-
67-
print("No valid ngrok URL found after retries.")
38+
response = requests.get(self.ngrok_api_url, timeout=self.timeout)
39+
tunnels = response.json().get('tunnels', [])
40+
for tunnel in tunnels:
41+
if tunnel.get('proto') == 'https':
42+
return tunnel['public_url']
6843
return None
69-
70-
except (subprocess.CalledProcessError, requests.RequestException) as e:
71-
print(f"Error starting ngrok: {e}")
44+
except requests.RequestException:
7245
return None
7346

7447
def setup_ngrok(self) -> None:
75-
"""Initialize ngrok and upload the URL to the gateway."""
76-
print("Setting up ngrok...")
77-
ngrok_url = self.start_ngrok()
78-
79-
if ngrok_url:
80-
print(f"ngrok started successfully with URL: {ngrok_url}")
81-
self.upload_ngrok_url_to_gateway(ngrok_url)
82-
else:
83-
print("Failed to start ngrok or retrieve the URL. Exiting setup.")
48+
"""Wait for ngrok to be ready and upload the URL to the gateway."""
49+
print("Waiting for ngrok to be ready...")
50+
retries = 30
51+
for attempt in range(retries):
52+
if self.check_ngrok_health():
53+
ngrok_url = self.get_ngrok_url()
54+
if ngrok_url:
55+
print(f"ngrok is ready with URL: {ngrok_url}")
56+
self.upload_ngrok_url_to_gateway(ngrok_url)
57+
return
58+
print(f"Waiting... ({attempt + 1}/{retries})")
59+
time.sleep(1)
60+
print("Failed to connect to ngrok after retries.")
8461

8562
def upload_ngrok_url_to_gateway(self, ngrok_url: str) -> bool:
8663
"""Upload the ngrok URL to the gateway server."""
8764
gateway_url = self.gateway_ngrok_url
8865
api_key = self.api_key
8966

9067
if not gateway_url or not api_key:
91-
print(f"Missing GATEWAY_NGROK_URL (\
92-
{gateway_url}) or API_KEY ({api_key})")
68+
print(
69+
f"Missing GATEWAY_NGROK_URL ({gateway_url}) or API_KEY ({api_key})")
9370
return False
9471

9572
try:
96-
print(f"Uploading ngrok URL ({ngrok_url}) to Gateway (\
97-
{gateway_url}) with API Key: {api_key}...")
73+
print(
74+
f"Uploading ngrok URL ({ngrok_url}) to Gateway ({gateway_url})")
9875
response = requests.post(
9976
gateway_url,
10077
json={'api_key': api_key, 'ngrok_url': ngrok_url},
@@ -103,10 +80,6 @@ def upload_ngrok_url_to_gateway(self, ngrok_url: str) -> bool:
10380
)
10481
response.raise_for_status()
10582
print("Successfully uploaded ngrok URL to Gateway.")
106-
# Confirm Gateway has the new URL
107-
confirm_response = requests.get(
108-
f"{gateway_url}/{api_key}", headers={'X-API-KEY': api_key}, timeout=self.timeout)
109-
print(f"Confirmed Gateway cache update: {confirm_response.json()}")
11083
return True
11184
except requests.exceptions.RequestException as e:
11285
print(f"Failed to upload ngrok URL to Gateway: {str(e)}")
@@ -118,35 +91,17 @@ def check_ngrok_status(self) -> bool:
11891
Returns:
11992
bool: Whether ngrok is correctly set up and gateway is updated.
12093
"""
121-
self.refresh_environment_variables() # Ensure class variables are up-to-date
94+
self.refresh_environment_variables()
12295
print("Checking ngrok status...")
123-
try:
124-
response = requests.get(self.ngrok_api_url, timeout=self.timeout)
125-
response.raise_for_status()
126-
tunnels = response.json().get("tunnels", [])
127-
print(f"Tunnel response: {tunnels}")
128-
129-
if tunnels:
130-
ngrok_url = tunnels[0].get("public_url")
131-
print(f"ngrok is running: {ngrok_url}")
13296

133-
if self.gateway_base_url is None:
134-
print("Warning: GATEWAY_BASE_URL is not correctly set.")
135-
return False
136-
137-
if ngrok_url.strip().lower() == self.gateway_base_url.strip().lower():
138-
print("ngrok URL is already synchronized with the gateway.")
139-
return True
140-
141-
print(f"ngrok URL has changed. Updating gateway with new URL: \
142-
{ngrok_url}")
143-
return self.upload_ngrok_url_to_gateway(ngrok_url)
144-
145-
print("No active ngrok tunnels found. Restarting ngrok...")
146-
self.setup_ngrok()
97+
if not self.check_ngrok_health():
98+
print("ngrok is not responding. Please check if it's running.")
14799
return False
148100

149-
except requests.exceptions.RequestException:
150-
print("ngrok is not running. Setting up ngrok...")
151-
self.setup_ngrok()
101+
ngrok_url = self.get_ngrok_url()
102+
if not ngrok_url:
103+
print("No active ngrok tunnels found.")
152104
return False
105+
106+
print(f"ngrok is running: {ngrok_url}")
107+
return self.upload_ngrok_url_to_gateway(ngrok_url)

0 commit comments

Comments
 (0)