def get_migrated_params( wf_module: WfModule, *, module_zipfile: ModuleZipfile = None) -> Dict[str, Any]: """ Read `wf_module.params`, calling migrate_params() or using cache fields. Call this within a `Workflow.cooperative_lock()`. If migrate_params() was already called for this version of the module, return the cached value. See `wf_module.cached_migrated_params`, `wf_module.cached_migrated_params_module_version`. Raise `ModuleError` if migration fails. Raise `KeyError` if the module was deleted. Raise `RuntimeError` (unrecoverable) if there is a problem loading or executing the module. (Modules are validated before import, so this should not happen.) The result may be invalid. Call `validate()` to raise a `ValueError` to detect that case. TODO avoid holding the database lock whilst executing stuff on the kernel. (This will involve auditing and modifying all callers to handle new error cases.) """ if module_zipfile is None: # raise KeyError module_zipfile = MODULE_REGISTRY.latest(wf_module.module_id_name) stale = ( module_zipfile.version == "develop" # works if cached version (and thus cached _result_) is None or (module_zipfile.get_param_schema_version() != wf_module.cached_migrated_params_module_version)) if not stale: return wf_module.cached_migrated_params else: # raise ModuleError params = invoke_migrate_params(module_zipfile, wf_module.params) wf_module.cached_migrated_params = params wf_module.cached_migrated_params_module_version = ( module_zipfile.get_param_schema_version()) try: wf_module.save(update_fields=[ "cached_migrated_params", "cached_migrated_params_module_version", ]) except ValueError: # WfModule was deleted, so we get: # "ValueError: Cannot force an update in save() with no primary key." pass return params
def get_migrated_params(wf_module: WfModule) -> Dict[str, Any]: """ Read `wf_module.params`, calling migrate_params() or using cache fields. Call this within a `Workflow.cooperative_lock()`. If migrate_params() was already called for this version of the module, return the cached value. See `wf_module.cached_migrated_params`, `wf_module.cached_migrated_params_module_version`. Raise `ModuleError` if migration fails. Return `{}` if the module was deleted. The result may be invalid. Call `validate()` to raise a `ValueError` to detect that case. """ module_version = wf_module.module_version if module_version is None: return {} if module_version.source_version_hash == "develop": stale = True elif ( # works if cached version (and thus cached _result_) is None module_version.param_schema_version != wf_module.cached_migrated_params_module_version): stale = True else: stale = False if not stale: return wf_module.cached_migrated_params else: loaded_module = LoadedModule.for_module_version(module_version) if loaded_module: params = wf_module.params # the user-supplied params params = loaded_module.migrate_params(params) # raises ModuleError wf_module.cached_migrated_params = params wf_module.cached_migrated_params_module_version = ( module_version.param_schema_version) # Write to DB, like wf_module.save(fields=[...]), even if the # WfModule was deleted in a race WfModule.objects.filter(id=wf_module.id).update( cached_migrated_params=wf_module.cached_migrated_params, cached_migrated_params_module_version=( wf_module.cached_migrated_params_module_version), ) return params else: return {}