Skip to content

Commit 25e7370

Browse files
committed
Strengthen timeout handling in api call
1 parent 234104d commit 25e7370

File tree

1 file changed

+84
-63
lines changed

1 file changed

+84
-63
lines changed

chipflow_lib/steps/silicon.py

Lines changed: 84 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121

2222
logger = logging.getLogger(__name__)
2323

24-
2524
class SiliconTop(StepBase, Elaboratable):
2625
def __init__(self, config={}):
2726
self._config = config
@@ -191,68 +190,7 @@ def submit(self, rtlil_path, *, dry_run=False, wait=False):
191190
resp_data = resp.text
192191

193192
# Handle response based on status code
194-
if resp.status_code == 200:
195-
logger.info(f"Submitted design: {resp_data}")
196-
build_url = f"{chipflow_api_origin}/build/{resp_data['build_id']}"
197-
build_status_url = f"{chipflow_api_origin}/build/{resp_data['build_id']}/status"
198-
log_stream_url = f"{chipflow_api_origin}/build/{resp_data['build_id']}/logs?follow=true"
199-
200-
print(f"Design submitted successfully! Build URL: {build_url}")
201-
202-
# Poll the status API until the build is completed or failed
203-
stream_event_counter = 0
204-
fail_counter = 0
205-
if wait:
206-
while True:
207-
logger.info("Polling build status...")
208-
status_resp = requests.get(
209-
build_status_url,
210-
auth=(None, chipflow_api_key)
211-
)
212-
if status_resp.status_code != 200:
213-
fail_counter += 1
214-
logger.error(f"Failed to fetch build status {fail_counter} times: {status_resp.text}")
215-
if fail_counter > 5:
216-
logger.error(f"Failed to fetch build status {fail_counter} times. Exiting.")
217-
raise ChipFlowError("Error while checking build status.")
218-
219-
status_data = status_resp.json()
220-
build_status = status_data.get("status")
221-
logger.info(f"Build status: {build_status}")
222-
223-
if build_status == "completed":
224-
print("Build completed successfully!")
225-
exit(0)
226-
elif build_status == "failed":
227-
print("Build failed.")
228-
exit(1)
229-
elif build_status == "running":
230-
print("Build running.")
231-
# Wait before polling again
232-
# time.sleep(10)
233-
# Attempt to stream logs rather than time.sleep
234-
try:
235-
if stream_event_counter > 1:
236-
logger.warning("Log streaming may have been interrupted. Some logs may be missing.")
237-
logger.warning(f"Check {build_url}")
238-
stream_event_counter += 1
239-
with requests.get(
240-
log_stream_url,
241-
auth=(None, chipflow_api_key),
242-
stream=True
243-
) as log_resp:
244-
if log_resp.status_code == 200:
245-
for line in log_resp.iter_lines():
246-
if line:
247-
print(line.decode("utf-8")) # Print logs in real-time
248-
sys.stdout.flush()
249-
else:
250-
logger.warning(f"Failed to stream logs: {log_resp.text}")
251-
except requests.RequestException as e:
252-
logger.error(f"Error while streaming logs: {e}")
253-
pass
254-
time.sleep(10) # Wait before polling again
255-
else:
193+
if resp.status_code != 200:
256194
# Log detailed information about the failed request
257195
logger.error(f"Request failed with status code {resp.status_code}")
258196
logger.error(f"Request URL: {resp.request.url}")
@@ -268,3 +206,86 @@ def submit(self, rtlil_path, *, dry_run=False, wait=False):
268206
logger.error(f"Response body: {resp_data}")
269207

270208
raise ChipFlowError(f"Failed to submit design: {resp_data}")
209+
210+
logger.info(f"Submitted design: {resp_data}")
211+
build_url = f"{chipflow_api_origin}/build/{resp_data['build_id']}"
212+
build_status_url = f"{chipflow_api_origin}/build/{resp_data['build_id']}/status"
213+
log_stream_url = f"{chipflow_api_origin}/build/{resp_data['build_id']}/logs?follow=true"
214+
215+
print(f"Design submitted successfully! Build URL: {build_url}")
216+
217+
# Poll the status API until the build is completed or failed
218+
warned_last = False
219+
timeout = 10.0
220+
221+
def stream_until_fail_or_done():
222+
nonlocal warned_last
223+
nonlocal timeout
224+
fail_count = 0
225+
while fail_count < (2*60//timeout):
226+
try:
227+
if fail_count > 1 and not warned_last:
228+
logger.warning("Log streaming may have been interrupted. Some logs may be missing.")
229+
logger.warning(f"Check {build_url}")
230+
warned_last = True
231+
with requests.get(
232+
log_stream_url,
233+
auth=(None, chipflow_api_key),
234+
stream=True, timeout=timeout
235+
) as log_resp:
236+
if log_resp.status_code == 200:
237+
warned_last = False
238+
for line in log_resp.iter_lines():
239+
if line:
240+
print(line.decode("utf-8")) # Print logs in real-time
241+
sys.stdout.flush()
242+
else:
243+
logger.warning(f"Failed to stream logs: {log_resp.text}")
244+
fail_count += 1
245+
except requests.Timeout:
246+
fail_count +=1
247+
continue #go round again
248+
except requests.RequestException as e:
249+
if type(e) is requests.exceptions.ConnectionError and e.response is None:
250+
fail_count +=1
251+
continue #try again
252+
logger.error(f"Error while streaming logs: {type(e)}:{e} response={e.response}")
253+
return "failed"
254+
status_data = status_resp.json()
255+
build_status = status_data.get("status")
256+
return build_status
257+
258+
259+
if not wait:
260+
exit(0)
261+
262+
fail_count = 0
263+
while True:
264+
logger.info("Polling build status...")
265+
try:
266+
status_resp = requests.get(
267+
build_status_url,
268+
auth=(None, chipflow_api_key),
269+
timeout=timeout
270+
)
271+
if status_resp.status_code != 200:
272+
fail_count += 1
273+
logger.error(f"Failed to fetch build status {fail_count} times: {status_resp.text}")
274+
if fail_count > 5:
275+
logger.error(f"Failed to fetch build status {fail_count} times. Exiting.")
276+
raise ChipFlowError("Error while checking build status.")
277+
except requests.Timeout:
278+
continue #go round again
279+
280+
build_status = stream_until_fail_or_done()
281+
if build_status == "completed":
282+
print("Build completed successfully!")
283+
exit(0)
284+
elif build_status == "failed":
285+
print("Build failed.")
286+
exit(1)
287+
elif build_status == "running":
288+
print("Build running.")
289+
# Wait before polling again
290+
time.sleep(0.5) # Wait before polling again
291+

0 commit comments

Comments
 (0)