2121
2222logger = logging .getLogger (__name__ )
2323
24-
2524class 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+ timeout = 10.0
219+
220+ def stream_until_fail_or_done ():
221+ nonlocal timeout
222+ fail_count = 0
223+ print_log_warning = False
224+ while fail_count < (2 * 60 // timeout ):
225+ try :
226+ if fail_count > 1 :
227+ print_log_warning = True
228+ with requests .get (
229+ log_stream_url ,
230+ auth = (None , chipflow_api_key ),
231+ stream = True , timeout = timeout
232+ ) as log_resp :
233+ if log_resp .status_code == 200 :
234+ for line in log_resp .iter_lines ():
235+ if line :
236+ print (line .decode ("utf-8" )) # Print logs in real-time
237+ sys .stdout .flush ()
238+ else :
239+ logger .warning (f"Failed to stream logs: { log_resp .text } " )
240+ fail_count += 1
241+ except requests .Timeout :
242+ fail_count += 1
243+ continue #go round again
244+ except requests .RequestException as e :
245+ if type (e ) is requests .exceptions .ConnectionError and e .response is None :
246+ fail_count += 1
247+ continue #try again
248+ logger .error (f"Error while streaming logs: { type (e )} :{ e } response={ e .response } " )
249+ return "failed"
250+ status_data = status_resp .json ()
251+ build_status = status_data .get ("status" )
252+ if print_log_warning :
253+ logger .warning ("Log streaming may have been interrupted. Some logs may be missing." )
254+ logger .warning (f"Check { build_url } " )
255+
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