def _execute_wfmodule_save(workflow: Workflow, wf_module: WfModule, result: ProcessResult) -> OutputDelta: """ Call wf_module.cache_render_result() and build OutputDelta. All this runs synchronously within a database lock. (It's a separate function so that when we're done awaiting it, we can continue executing in a context that doesn't use a database thread.) Raise UnneededExecution if the WfModule has changed in the interim. """ # raises UnneededExecution with locked_wf_module(workflow, wf_module) as safe_wf_module: if safe_wf_module.notifications: stale_crr = safe_wf_module.get_stale_cached_render_result() if stale_crr is None: stale_result = None else: # Read entire old Parquet file, blocking stale_result = stale_crr.result else: stale_result = None safe_wf_module.cache_render_result( safe_wf_module.last_relevant_delta_id, result) if safe_wf_module.notifications and result != stale_result: safe_wf_module.has_unseen_notification = True safe_wf_module.save(update_fields=["has_unseen_notification"]) return notifications.OutputDelta(safe_wf_module, stale_result, result) else: return None # nothing to email
def _execute_wfmodule_save(wf_module: WfModule, result: ProcessResult, old_result: ProcessResult) -> Tuple: """ Second database step of execute_wfmodule(). Writes result (and maybe has_unseen_notification) to the WfModule in the database and returns a Tuple in this order: * cached_render_result: the return value of execute_wfmodule(). * output_delta: if non-None, an OutputDelta to email to the Workflow owner. All this runs synchronously within a database lock. (It's a separate function so that when we're done awaiting it, we can continue executing in a context that doesn't use a database thread.) Raises UnneededExecution if the WfModule has changed in the interim. """ with locked_wf_module(wf_module) as safe_wf_module: if (safe_wf_module.last_relevant_delta_id != wf_module.last_relevant_delta_id): raise UnneededExecution cached_render_result = safe_wf_module.cache_render_result( safe_wf_module.last_relevant_delta_id, result) if safe_wf_module.notifications and result != old_result: safe_wf_module.has_unseen_notification = True output_delta = notifications.OutputDelta(safe_wf_module, old_result, result) else: output_delta = None # Save safe_wf_module, not wf_module, because we know we've only # changed the cached_render_result columns. (We know because we # locked the row before fetching it.) `wf_module.save()` might # overwrite some newer values. safe_wf_module.save() return (cached_render_result, output_delta)