Run submission in a separate thread, and more explicit state

Also more explicit timeouts and an overall better handling of errors.
This commit is contained in:
2018-08-14 16:36:43 +02:00
parent 5d86b87f40
commit b64577df2e
8 changed files with 191 additions and 66 deletions

View File

@@ -346,13 +346,22 @@ class BENCHMARK_PT_main(Panel):
sub.separator()
sub = col.row()
sub.enabled = not G.results_submitted
sub.enabled = G.state != G.State.submitting
sub.scale_y = 2.25
if G.submission_exception:
text = "Retry Submission"
text = "SHARE ONLINE"
if G.results_submitted and G.state != G.State.submitting:
if G.results_url:
# If we have a results URL, open it upon clicking the button
sub.operator("wm.url_open", text="Shared!").url = G.results_url
else:
sub.enabled = False
sub.operator("benchmark.share", text=text)
else:
text = "SHARE ONLINE"
sub.operator("benchmark.share", text=text)
if G.state == G.State.submitting:
text = "Submitting..."
elif G.submission_exception:
text = "Retry Submission"
sub.operator("benchmark.share", text=text)
sub = col.row()
subsub = sub.split()
@@ -368,18 +377,17 @@ class BENCHMARK_PT_main(Panel):
split.label()
def draw(self, context):
screen_index = 0
with G.progress_lock:
if G.result_dict:
screen_index = 2
elif G.result_stats or G.progress_status:
screen_index = 1
state = G.state
if screen_index == 0:
self.draw_welcome(context)
elif screen_index == 2:
self.draw_submit(context)
draw_funcs = {
G.State.welcome: self.draw_welcome,
G.State.complete: self.draw_submit,
G.State.submitting: self.draw_submit,
}
func = draw_funcs.get(state, None)
if func:
func(context)
################################################################################
@@ -488,8 +496,10 @@ class BENCHMARK_OT_run_base(bpy.types.Operator):
else:
G.result_stats += "{}: {}".format(name_stat['name'],
stat["result"])
G.state = G.State.complete
else:
G.result_stats = ""
G.state = G.State.welcome
# TOGO(sergey): Use some more nice picture for the final slide.
G.background_image_path = ""
# Tag for nice redraw
@@ -513,9 +523,11 @@ class BENCHMARK_OT_run_base(bpy.types.Operator):
return {'PASS_THROUGH'}
def invoke(self, context, event):
G.cancel = False
G.result_platform = ""
G.progress_status = "Initializing..."
with G.progress_lock:
G.cancel = False
G.result_platform = ""
G.progress_status = "Initializing..."
G.state = G.State.running
context.area.tag_redraw()
compute_device = context.scene.compute_device
@@ -630,30 +642,44 @@ class BENCHMARK_OT_share(bpy.types.Operator):
bl_idname = "benchmark.share"
bl_label = "Share Benchmark Result"
def execute(self, context):
timer = None
thread = None
def modal(self, context, event):
if event.type == 'TIMER':
if self.thread.is_alive():
context.area.tag_redraw()
return {'PASS_THROUGH'}
else:
self.done(context)
return {'FINISHED'}
return {'PASS_THROUGH'}
def invoke(self, context, event):
from benchmark import submission
make_buttons_default()
print('Submitting benchmark')
G.submission_exception = None
try:
submission.submit_benchmark(G.result_dict)
except submission.CommunicationError as cex:
logger.ERROR(f'Error {cex.status_code} submitting benchmark: {cex.message}')
if cex.json:
logger.ERROR(f'Response JSON: {cex.json}')
else:
logger.ERROR(f'Response body: {cex.body}')
G.submission_exception = cex
return {'CANCELLED'}
except Exception as ex:
logger.ERROR(f'error submitting benchmark: {ex}')
G.submission_exception = ex
return {'CANCELLED'}
print('Submission done')
self.thread = submission.submit_benchmark_bgthread(G.result_dict)
# Create timer to query thread status
wm = context.window_manager
self.timer = wm.event_timer_add(0.1, context.window)
# Register self as modal.
context.window_manager.modal_handler_add(self)
return {'RUNNING_MODAL'}
def done(self, context):
make_buttons_green()
G.results_submitted = True
return {'FINISHED'}
if self.timer:
wm = context.window_manager
wm.event_timer_remove(self.timer)
if self.thread:
self.thread.join()
context.area.tag_redraw()
class BENCHMARK_OT_opendata_link(bpy.types.Operator):