-
Notifications
You must be signed in to change notification settings - Fork 0
Part of support non editable workflows: discovery end-point #247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
d9fe79b
bc638d3
b029971
98c2368
ff286fe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,165 @@ | ||
| import logging | ||
|
|
||
| from ewoksjob.client import discover_all_tasks | ||
| from ewoksjob.client import discover_all_workflows | ||
| from ewoksjob.client import discover_tasks_from_modules | ||
| from ewoksjob.client import discover_workflows_from_modules | ||
| from ewoksjob.client import get_queues | ||
| from ewoksjob.client.local import discover_all_tasks as discover_all_tasks_local | ||
| from ewoksjob.client.local import discover_all_workflows as discover_all_workflows_local | ||
| from ewoksjob.client.local import ( | ||
| discover_tasks_from_modules as discover_tasks_from_modules_local, | ||
| ) | ||
| from ewoksjob.client.local import ( | ||
| discover_workflows_from_modules as discover_workflows_from_modules_local, | ||
| ) | ||
|
|
||
| from ...config import EwoksSettings | ||
| from ...models import EwoksSchedulingType | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| def discover_tasks( | ||
| settings: EwoksSettings, | ||
| modules: list[str] | None = None, | ||
| reload: bool | None = None, | ||
| task_type: str | None = None, | ||
| worker_options: dict | None = None, | ||
| ) -> list[dict[str, str]]: | ||
| """ | ||
| :raises ModuleNotFoundError: failed importing tasks. | ||
| :raises TimeoutError: timeout when asking a remote worker for tasks. | ||
| :raises Exception: any other import or remote error. | ||
| """ | ||
| if settings.ewoks_scheduling.type == EwoksSchedulingType.Local: | ||
| if modules: | ||
| discover = discover_tasks_from_modules_local | ||
| else: | ||
| discover = discover_all_tasks_local | ||
| else: | ||
| if modules: | ||
| discover = discover_tasks_from_modules | ||
| else: | ||
| discover = discover_all_tasks | ||
|
|
||
| discover_kwargs = dict() | ||
| if reload is not None: | ||
| discover_kwargs["reload"] = reload | ||
| if task_type is not None: | ||
| discover_kwargs["task_type"] = task_type | ||
|
|
||
| tasks = _discover( | ||
| discover, | ||
| settings, | ||
| modules=modules, | ||
| discover_kwargs=discover_kwargs, | ||
| worker_options=worker_options, | ||
| key=lambda task: task["task_identifier"], | ||
| ) | ||
|
|
||
| for task in tasks: | ||
| _set_default_task_properties(task) | ||
| return tasks | ||
|
|
||
|
|
||
| def discover_workflows( | ||
| settings: EwoksSettings, | ||
| modules: list[str] | None = None, | ||
| workflow_extension: str | None = None, | ||
| worker_options: dict | None = None, | ||
| ) -> list[str]: | ||
| """ | ||
| :raises ModuleNotFoundError: failed importing workflows. | ||
| :raises TimeoutError: timeout when asking a remote worker for workflows. | ||
| :raises Exception: any other import or remote error. | ||
| """ | ||
| if settings.ewoks_scheduling.type == EwoksSchedulingType.Local: | ||
| if modules: | ||
| discover = discover_workflows_from_modules_local | ||
| else: | ||
| discover = discover_all_workflows_local | ||
| else: | ||
| if modules: | ||
| discover = discover_workflows_from_modules | ||
| else: | ||
| discover = discover_all_workflows | ||
|
|
||
| discover_kwargs = dict() | ||
| if workflow_extension is not None: | ||
| discover_kwargs["workflow_extension"] = workflow_extension | ||
|
|
||
| return _discover( | ||
| discover, | ||
| settings, | ||
| modules=modules, | ||
| discover_kwargs=discover_kwargs, | ||
| worker_options=worker_options, | ||
| key=lambda workflow: workflow, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should it not be workflow id here?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In contrast to task discovery which returns For the variable name is |
||
| ) | ||
|
|
||
|
|
||
| def _discover( | ||
| discover, | ||
| settings: EwoksSettings, | ||
| modules: list[str] | None, | ||
| discover_kwargs: dict, | ||
| worker_options: dict | None, | ||
| key, | ||
| ) -> list: | ||
| """ | ||
| :raises ModuleNotFoundError: failed importing tasks or workflows. | ||
| :raises TimeoutError: timeout when asking a remote worker. | ||
| :raises Exception: any other import or remote error. | ||
| """ | ||
| if worker_options is None: | ||
| kwargs = dict() | ||
| else: | ||
| kwargs = dict(worker_options) | ||
|
|
||
| # Discovery: position arguments | ||
| if modules: | ||
| kwargs["args"] = modules | ||
|
|
||
| # Discovery: named arguments | ||
| kwargs["kwargs"] = discover_kwargs | ||
|
|
||
| timeout = settings.ewoks_discovery.timeout | ||
| if settings.ewoks_scheduling.type == EwoksSchedulingType.Local: | ||
| return _discover_locally(discover, kwargs, timeout=timeout) | ||
| else: | ||
| return _discover_in_all_queues(discover, kwargs, key, timeout=timeout) | ||
|
|
||
|
|
||
| def _discover_locally(discover, kwargs: dict, timeout: float | None = None) -> list: | ||
| return discover(**kwargs).result(timeout=timeout) | ||
|
|
||
|
|
||
| def _discover_in_all_queues( | ||
| discover, kwargs: dict, key, timeout: float | None = None | ||
| ) -> list: | ||
| futures = [discover(**kwargs, queue=queue) for queue in get_queues()] | ||
|
|
||
| # Store items in a dict to avoid duplicates | ||
| item_dict = {} | ||
| for future in futures: | ||
| # Ignore failures of a single queue to not prevent discovery on other queues | ||
| new_items = future.result(timeout=timeout) | ||
| exc = future.exception() | ||
| if exc: | ||
| logger.warning(f"Discovery failed for {future.queue}: {exc}") | ||
| continue | ||
| if new_items is None: | ||
| continue | ||
| for item in new_items: | ||
| item_dict[key(item)] = item | ||
| return list(item_dict.values()) | ||
|
|
||
|
|
||
| def _set_default_task_properties(task: dict) -> None: | ||
| if not task.get("icon"): | ||
| task["icon"] = "default.png" | ||
| if not task.get("label"): | ||
| task_identifier = task.get("task_identifier") | ||
| if task_identifier: | ||
| task["label"] = task_identifier.split(".")[-1] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,4 +4,5 @@ | |
| (1, 0, 0): _router, | ||
| (1, 1, 0): _router, | ||
| (2, 0, 0): _router, | ||
| (2, 1, 0): _router, | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,4 +4,5 @@ | |
| (1, 0, 0): _router, | ||
| (1, 1, 0): _router, | ||
| (2, 0, 0): _router, | ||
| (2, 1, 0): _router, | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactor the task discovery to do both task and workflow discovery.