fractal-server 2.13.1__py3-none-any.whl → 2.14.0a0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fractal_server/__init__.py +1 -1
- fractal_server/app/history/__init__.py +4 -0
- fractal_server/app/history/image_updates.py +142 -0
- fractal_server/app/history/status_enum.py +16 -0
- fractal_server/app/models/v2/__init__.py +5 -1
- fractal_server/app/models/v2/history.py +53 -0
- fractal_server/app/routes/api/v2/__init__.py +2 -2
- fractal_server/app/routes/api/v2/_aux_functions.py +78 -0
- fractal_server/app/routes/api/v2/dataset.py +12 -9
- fractal_server/app/routes/api/v2/history.py +247 -0
- fractal_server/app/routes/api/v2/workflow.py +18 -3
- fractal_server/app/routes/api/v2/workflowtask.py +22 -0
- fractal_server/app/runner/executors/base_runner.py +114 -0
- fractal_server/app/runner/{v2/_local → executors/local}/_local_config.py +3 -3
- fractal_server/app/runner/executors/local/_submit_setup.py +54 -0
- fractal_server/app/runner/executors/local/runner.py +200 -0
- fractal_server/app/runner/executors/{slurm → slurm_common}/_batching.py +1 -1
- fractal_server/app/runner/executors/{slurm → slurm_common}/_slurm_config.py +3 -3
- fractal_server/app/runner/{v2/_slurm_ssh → executors/slurm_common}/_submit_setup.py +13 -12
- fractal_server/app/runner/{v2/_slurm_common → executors/slurm_common}/get_slurm_config.py +9 -15
- fractal_server/app/runner/executors/{slurm/ssh → slurm_ssh}/_executor_wait_thread.py +1 -1
- fractal_server/app/runner/executors/{slurm/ssh → slurm_ssh}/_slurm_job.py +1 -1
- fractal_server/app/runner/executors/{slurm/ssh → slurm_ssh}/executor.py +13 -14
- fractal_server/app/runner/executors/{slurm/sudo → slurm_sudo}/_check_jobs_status.py +11 -9
- fractal_server/app/runner/executors/{slurm/sudo → slurm_sudo}/_executor_wait_thread.py +3 -3
- fractal_server/app/runner/executors/{slurm/sudo → slurm_sudo}/_subprocess_run_as_user.py +2 -68
- fractal_server/app/runner/executors/slurm_sudo/runner.py +632 -0
- fractal_server/app/runner/task_files.py +70 -96
- fractal_server/app/runner/v2/__init__.py +5 -19
- fractal_server/app/runner/v2/_local.py +84 -0
- fractal_server/app/runner/v2/{_slurm_ssh/__init__.py → _slurm_ssh.py} +10 -13
- fractal_server/app/runner/v2/{_slurm_sudo/__init__.py → _slurm_sudo.py} +10 -12
- fractal_server/app/runner/v2/runner.py +93 -28
- fractal_server/app/runner/v2/runner_functions.py +85 -62
- fractal_server/app/runner/v2/runner_functions_low_level.py +20 -20
- fractal_server/app/schemas/v2/dataset.py +0 -17
- fractal_server/app/schemas/v2/history.py +23 -0
- fractal_server/config.py +2 -2
- fractal_server/migrations/versions/8223fcef886c_image_status.py +63 -0
- fractal_server/migrations/versions/87cd72a537a2_add_historyitem_table.py +68 -0
- {fractal_server-2.13.1.dist-info → fractal_server-2.14.0a0.dist-info}/METADATA +1 -1
- {fractal_server-2.13.1.dist-info → fractal_server-2.14.0a0.dist-info}/RECORD +52 -46
- fractal_server/app/routes/api/v2/status.py +0 -168
- fractal_server/app/runner/executors/slurm/sudo/executor.py +0 -1281
- fractal_server/app/runner/v2/_local/__init__.py +0 -132
- fractal_server/app/runner/v2/_local/_submit_setup.py +0 -52
- fractal_server/app/runner/v2/_local/executor.py +0 -100
- fractal_server/app/runner/v2/_slurm_sudo/_submit_setup.py +0 -83
- fractal_server/app/runner/v2/handle_failed_job.py +0 -59
- /fractal_server/app/runner/executors/{slurm → local}/__init__.py +0 -0
- /fractal_server/app/runner/executors/{slurm/ssh → slurm_common}/__init__.py +0 -0
- /fractal_server/app/runner/executors/{_job_states.py → slurm_common/_job_states.py} +0 -0
- /fractal_server/app/runner/executors/{slurm → slurm_common}/remote.py +0 -0
- /fractal_server/app/runner/executors/{slurm → slurm_common}/utils_executors.py +0 -0
- /fractal_server/app/runner/executors/{slurm/sudo → slurm_ssh}/__init__.py +0 -0
- /fractal_server/app/runner/{v2/_slurm_common → executors/slurm_sudo}/__init__.py +0 -0
- {fractal_server-2.13.1.dist-info → fractal_server-2.14.0a0.dist-info}/LICENSE +0 -0
- {fractal_server-2.13.1.dist-info → fractal_server-2.14.0a0.dist-info}/WHEEL +0 -0
- {fractal_server-2.13.1.dist-info → fractal_server-2.14.0a0.dist-info}/entry_points.txt +0 -0
@@ -1,132 +0,0 @@
|
|
1
|
-
# Copyright 2022 (C) Friedrich Miescher Institute for Biomedical Research and
|
2
|
-
# University of Zurich
|
3
|
-
#
|
4
|
-
# Original authors:
|
5
|
-
# Jacopo Nespolo <jacopo.nespolo@exact-lab.it>
|
6
|
-
# Tommaso Comparin <tommaso.comparin@exact-lab.it>
|
7
|
-
# Marco Franzon <marco.franzon@exact-lab.it>
|
8
|
-
#
|
9
|
-
# This file is part of Fractal and was originally developed by eXact lab S.r.l.
|
10
|
-
# <exact-lab.it> under contract with Liberali Lab from the Friedrich Miescher
|
11
|
-
# Institute for Biomedical Research and Pelkmans Lab from the University of
|
12
|
-
# Zurich.
|
13
|
-
"""
|
14
|
-
Local Bakend
|
15
|
-
|
16
|
-
This backend runs Fractal workflows using `FractalThreadPoolExecutor` (a custom
|
17
|
-
version of Python
|
18
|
-
[ThreadPoolExecutor](https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor))
|
19
|
-
to run tasks in several threads.
|
20
|
-
Incidentally, it also represents the reference implementation for a backend.
|
21
|
-
"""
|
22
|
-
from pathlib import Path
|
23
|
-
from typing import Optional
|
24
|
-
|
25
|
-
from ....models.v2 import DatasetV2
|
26
|
-
from ....models.v2 import WorkflowV2
|
27
|
-
from ...set_start_and_last_task_index import set_start_and_last_task_index
|
28
|
-
from ..runner import execute_tasks_v2
|
29
|
-
from ._submit_setup import _local_submit_setup
|
30
|
-
from .executor import FractalThreadPoolExecutor
|
31
|
-
from fractal_server.images.models import AttributeFiltersType
|
32
|
-
|
33
|
-
|
34
|
-
def process_workflow(
|
35
|
-
*,
|
36
|
-
workflow: WorkflowV2,
|
37
|
-
dataset: DatasetV2,
|
38
|
-
workflow_dir_local: Path,
|
39
|
-
workflow_dir_remote: Optional[Path] = None,
|
40
|
-
first_task_index: Optional[int] = None,
|
41
|
-
last_task_index: Optional[int] = None,
|
42
|
-
logger_name: str,
|
43
|
-
job_attribute_filters: AttributeFiltersType,
|
44
|
-
user_id: int,
|
45
|
-
# Slurm-specific
|
46
|
-
user_cache_dir: Optional[str] = None,
|
47
|
-
slurm_user: Optional[str] = None,
|
48
|
-
slurm_account: Optional[str] = None,
|
49
|
-
worker_init: Optional[str] = None,
|
50
|
-
) -> None:
|
51
|
-
"""
|
52
|
-
Run a workflow
|
53
|
-
|
54
|
-
This function is responsible for running a workflow on some input data,
|
55
|
-
saving the output and taking care of any exception raised during the run.
|
56
|
-
|
57
|
-
NOTE: This is the `local` backend's public interface, which also works as
|
58
|
-
a reference implementation for other backends.
|
59
|
-
|
60
|
-
Args:
|
61
|
-
workflow:
|
62
|
-
The workflow to be run
|
63
|
-
dataset:
|
64
|
-
Initial dataset.
|
65
|
-
workflow_dir_local:
|
66
|
-
Working directory for this run.
|
67
|
-
workflow_dir_remote:
|
68
|
-
Working directory for this run, on the user side. This argument is
|
69
|
-
present for compatibility with the standard backend interface, but
|
70
|
-
for the `local` backend it cannot be different from
|
71
|
-
`workflow_dir_local`.
|
72
|
-
first_task_index:
|
73
|
-
Positional index of the first task to execute; if `None`, start
|
74
|
-
from `0`.
|
75
|
-
last_task_index:
|
76
|
-
Positional index of the last task to execute; if `None`, proceed
|
77
|
-
until the last task.
|
78
|
-
logger_name: Logger name
|
79
|
-
user_id:
|
80
|
-
slurm_user:
|
81
|
-
Username to impersonate to run the workflow. This argument is
|
82
|
-
present for compatibility with the standard backend interface, but
|
83
|
-
is ignored in the `local` backend.
|
84
|
-
slurm_account:
|
85
|
-
SLURM account to use when running the workflow. This argument is
|
86
|
-
present for compatibility with the standard backend interface, but
|
87
|
-
is ignored in the `local` backend.
|
88
|
-
user_cache_dir:
|
89
|
-
Cache directory of the user who will run the workflow. This
|
90
|
-
argument is present for compatibility with the standard backend
|
91
|
-
interface, but is ignored in the `local` backend.
|
92
|
-
worker_init:
|
93
|
-
Any additional, usually backend specific, information to be passed
|
94
|
-
to the backend executor. This argument is present for compatibility
|
95
|
-
with the standard backend interface, but is ignored in the `local`
|
96
|
-
backend.
|
97
|
-
|
98
|
-
Raises:
|
99
|
-
TaskExecutionError: wrapper for errors raised during tasks' execution
|
100
|
-
(positive exit codes).
|
101
|
-
JobExecutionError: wrapper for errors raised by the tasks' executors
|
102
|
-
(negative exit codes).
|
103
|
-
"""
|
104
|
-
|
105
|
-
if workflow_dir_remote and (workflow_dir_remote != workflow_dir_local):
|
106
|
-
raise NotImplementedError(
|
107
|
-
"Local backend does not support different directories "
|
108
|
-
f"{workflow_dir_local=} and {workflow_dir_remote=}"
|
109
|
-
)
|
110
|
-
|
111
|
-
# Set values of first_task_index and last_task_index
|
112
|
-
num_tasks = len(workflow.task_list)
|
113
|
-
first_task_index, last_task_index = set_start_and_last_task_index(
|
114
|
-
num_tasks,
|
115
|
-
first_task_index=first_task_index,
|
116
|
-
last_task_index=last_task_index,
|
117
|
-
)
|
118
|
-
|
119
|
-
with FractalThreadPoolExecutor() as executor:
|
120
|
-
execute_tasks_v2(
|
121
|
-
wf_task_list=workflow.task_list[
|
122
|
-
first_task_index : (last_task_index + 1)
|
123
|
-
],
|
124
|
-
dataset=dataset,
|
125
|
-
executor=executor,
|
126
|
-
workflow_dir_local=workflow_dir_local,
|
127
|
-
workflow_dir_remote=workflow_dir_local,
|
128
|
-
logger_name=logger_name,
|
129
|
-
submit_setup_call=_local_submit_setup,
|
130
|
-
job_attribute_filters=job_attribute_filters,
|
131
|
-
user_id=user_id,
|
132
|
-
)
|
@@ -1,52 +0,0 @@
|
|
1
|
-
# Copyright 2022 (C) Friedrich Miescher Institute for Biomedical Research and
|
2
|
-
# University of Zurich
|
3
|
-
#
|
4
|
-
# Original authors:
|
5
|
-
# Tommaso Comparin <tommaso.comparin@exact-lab.it>
|
6
|
-
#
|
7
|
-
# This file is part of Fractal and was originally developed by eXact lab S.r.l.
|
8
|
-
# <exact-lab.it> under contract with Liberali Lab from the Friedrich Miescher
|
9
|
-
# Institute for Biomedical Research and Pelkmans Lab from the University of
|
10
|
-
# Zurich.
|
11
|
-
"""
|
12
|
-
Submodule to define _local_submit_setup
|
13
|
-
"""
|
14
|
-
from pathlib import Path
|
15
|
-
from typing import Literal
|
16
|
-
from typing import Optional
|
17
|
-
|
18
|
-
from ....models.v2 import WorkflowTaskV2
|
19
|
-
from ._local_config import get_local_backend_config
|
20
|
-
|
21
|
-
|
22
|
-
def _local_submit_setup(
|
23
|
-
*,
|
24
|
-
wftask: WorkflowTaskV2,
|
25
|
-
workflow_dir_local: Optional[Path] = None,
|
26
|
-
workflow_dir_remote: Optional[Path] = None,
|
27
|
-
which_type: Literal["non_parallel", "parallel"],
|
28
|
-
) -> dict[str, object]:
|
29
|
-
"""
|
30
|
-
Collect WorfklowTask-specific configuration parameters from different
|
31
|
-
sources, and inject them for execution.
|
32
|
-
|
33
|
-
Arguments:
|
34
|
-
wftask:
|
35
|
-
WorkflowTask for which the configuration is to be assembled
|
36
|
-
workflow_dir_local:
|
37
|
-
Not used in this function.
|
38
|
-
workflow_dir_remote:
|
39
|
-
Not used in this function.
|
40
|
-
|
41
|
-
Returns:
|
42
|
-
submit_setup_dict:
|
43
|
-
A dictionary that will be passed on to
|
44
|
-
`FractalThreadPoolExecutor.submit` and
|
45
|
-
`FractalThreadPoolExecutor.map`, so as to set extra options.
|
46
|
-
"""
|
47
|
-
|
48
|
-
local_backend_config = get_local_backend_config(
|
49
|
-
wftask=wftask, which_type=which_type
|
50
|
-
)
|
51
|
-
|
52
|
-
return dict(local_backend_config=local_backend_config)
|
@@ -1,100 +0,0 @@
|
|
1
|
-
# Copyright 2022 (C) Friedrich Miescher Institute for Biomedical Research and
|
2
|
-
# University of Zurich
|
3
|
-
#
|
4
|
-
# Original authors:
|
5
|
-
# Tommaso Comparin <tommaso.comparin@exact-lab.it>
|
6
|
-
#
|
7
|
-
# This file is part of Fractal and was originally developed by eXact lab S.r.l.
|
8
|
-
# <exact-lab.it> under contract with Liberali Lab from the Friedrich Miescher
|
9
|
-
# Institute for Biomedical Research and Pelkmans Lab from the University of
|
10
|
-
# Zurich.
|
11
|
-
"""
|
12
|
-
Custom version of Python
|
13
|
-
[ThreadPoolExecutor](https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor)).
|
14
|
-
"""
|
15
|
-
from concurrent.futures import ThreadPoolExecutor
|
16
|
-
from typing import Callable
|
17
|
-
from typing import Iterable
|
18
|
-
from typing import Optional
|
19
|
-
from typing import Sequence
|
20
|
-
|
21
|
-
from ._local_config import get_default_local_backend_config
|
22
|
-
from ._local_config import LocalBackendConfig
|
23
|
-
|
24
|
-
|
25
|
-
class FractalThreadPoolExecutor(ThreadPoolExecutor):
|
26
|
-
"""
|
27
|
-
Custom version of
|
28
|
-
[ThreadPoolExecutor](https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor))
|
29
|
-
that overrides the `submit` and `map` methods
|
30
|
-
"""
|
31
|
-
|
32
|
-
def submit(
|
33
|
-
self,
|
34
|
-
*args,
|
35
|
-
local_backend_config: Optional[LocalBackendConfig] = None,
|
36
|
-
**kwargs,
|
37
|
-
):
|
38
|
-
"""
|
39
|
-
Compared to the `ThreadPoolExecutor` method, here we accept an addition
|
40
|
-
keyword argument (`local_backend_config`), which is then simply
|
41
|
-
ignored.
|
42
|
-
"""
|
43
|
-
return super().submit(*args, **kwargs)
|
44
|
-
|
45
|
-
def map(
|
46
|
-
self,
|
47
|
-
fn: Callable,
|
48
|
-
*iterables: Sequence[Iterable],
|
49
|
-
local_backend_config: Optional[LocalBackendConfig] = None,
|
50
|
-
):
|
51
|
-
"""
|
52
|
-
Custom version of the `Executor.map` method
|
53
|
-
|
54
|
-
The main change with the respect to the original `map` method is that
|
55
|
-
the list of tasks to be executed is split into chunks, and then
|
56
|
-
`super().map` is called (sequentially) on each chunk. The goal of this
|
57
|
-
change is to limit parallelism, e.g. due to limited computational
|
58
|
-
resources.
|
59
|
-
|
60
|
-
Other changes from the `concurrent.futures` `map` method:
|
61
|
-
|
62
|
-
1. Removed `timeout` argument;
|
63
|
-
2. Removed `chunksize`;
|
64
|
-
3. All iterators (both inputs and output ones) are transformed into
|
65
|
-
lists.
|
66
|
-
|
67
|
-
Args:
|
68
|
-
fn: A callable function.
|
69
|
-
iterables: The argument iterables (one iterable per argument of
|
70
|
-
`fn`).
|
71
|
-
local_backend_config: The backend configuration, needed to extract
|
72
|
-
`parallel_tasks_per_job`.
|
73
|
-
"""
|
74
|
-
|
75
|
-
# Preliminary check
|
76
|
-
iterable_lengths = [len(it) for it in iterables]
|
77
|
-
if not len(set(iterable_lengths)) == 1:
|
78
|
-
raise ValueError("Iterables have different lengths.")
|
79
|
-
|
80
|
-
# Set total number of arguments
|
81
|
-
n_elements = len(iterables[0])
|
82
|
-
|
83
|
-
# Set parallel_tasks_per_job
|
84
|
-
if local_backend_config is None:
|
85
|
-
local_backend_config = get_default_local_backend_config()
|
86
|
-
parallel_tasks_per_job = local_backend_config.parallel_tasks_per_job
|
87
|
-
if parallel_tasks_per_job is None:
|
88
|
-
parallel_tasks_per_job = n_elements
|
89
|
-
|
90
|
-
# Execute tasks, in chunks of size parallel_tasks_per_job
|
91
|
-
results = []
|
92
|
-
for ind_chunk in range(0, n_elements, parallel_tasks_per_job):
|
93
|
-
chunk_iterables = [
|
94
|
-
it[ind_chunk : ind_chunk + parallel_tasks_per_job] # noqa
|
95
|
-
for it in iterables
|
96
|
-
]
|
97
|
-
map_iter = super().map(fn, *chunk_iterables)
|
98
|
-
results.extend(list(map_iter))
|
99
|
-
|
100
|
-
return iter(results)
|
@@ -1,83 +0,0 @@
|
|
1
|
-
# Copyright 2022 (C) Friedrich Miescher Institute for Biomedical Research and
|
2
|
-
# University of Zurich
|
3
|
-
#
|
4
|
-
# Original authors:
|
5
|
-
# Jacopo Nespolo <jacopo.nespolo@exact-lab.it>
|
6
|
-
# Tommaso Comparin <tommaso.comparin@exact-lab.it>
|
7
|
-
#
|
8
|
-
# This file is part of Fractal and was originally developed by eXact lab S.r.l.
|
9
|
-
# <exact-lab.it> under contract with Liberali Lab from the Friedrich Miescher
|
10
|
-
# Institute for Biomedical Research and Pelkmans Lab from the University of
|
11
|
-
# Zurich.
|
12
|
-
"""
|
13
|
-
Submodule to define _slurm_submit_setup, which is also the reference
|
14
|
-
implementation of `submit_setup_call`.
|
15
|
-
"""
|
16
|
-
from pathlib import Path
|
17
|
-
from typing import Literal
|
18
|
-
|
19
|
-
from ...task_files import get_task_file_paths
|
20
|
-
from fractal_server.app.models.v2 import WorkflowTaskV2
|
21
|
-
from fractal_server.app.runner.v2._slurm_common.get_slurm_config import (
|
22
|
-
get_slurm_config,
|
23
|
-
)
|
24
|
-
|
25
|
-
|
26
|
-
def _slurm_submit_setup(
|
27
|
-
*,
|
28
|
-
wftask: WorkflowTaskV2,
|
29
|
-
workflow_dir_local: Path,
|
30
|
-
workflow_dir_remote: Path,
|
31
|
-
which_type: Literal["non_parallel", "parallel"],
|
32
|
-
) -> dict[str, object]:
|
33
|
-
"""
|
34
|
-
Collect WorfklowTask-specific configuration parameters from different
|
35
|
-
sources, and inject them for execution.
|
36
|
-
|
37
|
-
Here goes all the logic for reading attributes from the appropriate sources
|
38
|
-
and transforming them into an appropriate `SlurmConfig` object (encoding
|
39
|
-
SLURM configuration) and `TaskFiles` object (with details e.g. about file
|
40
|
-
paths or filename prefixes).
|
41
|
-
|
42
|
-
For now, this is the reference implementation for the argument
|
43
|
-
`submit_setup_call` of
|
44
|
-
[fractal_server.app.runner.v2.runner][].
|
45
|
-
|
46
|
-
Arguments:
|
47
|
-
wftask:
|
48
|
-
WorkflowTask for which the configuration is to be assembled
|
49
|
-
workflow_dir_local:
|
50
|
-
Server-owned directory to store all task-execution-related relevant
|
51
|
-
files (inputs, outputs, errors, and all meta files related to the
|
52
|
-
job execution). Note: users cannot write directly to this folder.
|
53
|
-
workflow_dir_remote:
|
54
|
-
User-side directory with the same scope as `workflow_dir_local`,
|
55
|
-
and where a user can write.
|
56
|
-
|
57
|
-
Returns:
|
58
|
-
submit_setup_dict:
|
59
|
-
A dictionary that will be passed on to
|
60
|
-
`FractalSlurmExecutor.submit` and `FractalSlurmExecutor.map`, so
|
61
|
-
as to set extra options.
|
62
|
-
"""
|
63
|
-
|
64
|
-
# Get SlurmConfig object
|
65
|
-
slurm_config = get_slurm_config(
|
66
|
-
wftask=wftask,
|
67
|
-
which_type=which_type,
|
68
|
-
)
|
69
|
-
|
70
|
-
# Get TaskFiles object
|
71
|
-
task_files = get_task_file_paths(
|
72
|
-
workflow_dir_local=workflow_dir_local,
|
73
|
-
workflow_dir_remote=workflow_dir_remote,
|
74
|
-
task_order=wftask.order,
|
75
|
-
task_name=wftask.task.name,
|
76
|
-
)
|
77
|
-
|
78
|
-
# Prepare and return output dictionary
|
79
|
-
submit_setup_dict = dict(
|
80
|
-
slurm_config=slurm_config,
|
81
|
-
task_files=task_files,
|
82
|
-
)
|
83
|
-
return submit_setup_dict
|
@@ -1,59 +0,0 @@
|
|
1
|
-
# Copyright 2022 (C) Friedrich Miescher Institute for Biomedical Research and
|
2
|
-
# University of Zurich
|
3
|
-
#
|
4
|
-
# Original authors:
|
5
|
-
# Tommaso Comparin <tommaso.comparin@exact-lab.it>
|
6
|
-
# Marco Franzon <marco.franzon@exact-lab.it>
|
7
|
-
#
|
8
|
-
# This file is part of Fractal and was originally developed by eXact lab S.r.l.
|
9
|
-
# <exact-lab.it> under contract with Liberali Lab from the Friedrich Miescher
|
10
|
-
# Institute for Biomedical Research and Pelkmans Lab from the University of
|
11
|
-
# Zurich.
|
12
|
-
"""
|
13
|
-
Helper functions to handle Dataset history.
|
14
|
-
"""
|
15
|
-
import logging
|
16
|
-
|
17
|
-
from sqlalchemy.orm.attributes import flag_modified
|
18
|
-
|
19
|
-
from ...models.v2 import DatasetV2
|
20
|
-
from ...schemas.v2 import WorkflowTaskStatusTypeV2
|
21
|
-
from fractal_server.app.db import get_sync_db
|
22
|
-
|
23
|
-
|
24
|
-
def mark_last_wftask_as_failed(
|
25
|
-
dataset_id: int,
|
26
|
-
logger_name: str,
|
27
|
-
) -> None:
|
28
|
-
"""
|
29
|
-
Edit dataset history, by marking last item as failed.
|
30
|
-
|
31
|
-
Args:
|
32
|
-
dataset: The `DatasetV2` object
|
33
|
-
logger_name: A logger name.
|
34
|
-
"""
|
35
|
-
|
36
|
-
logger = logging.getLogger(logger_name)
|
37
|
-
with next(get_sync_db()) as db:
|
38
|
-
db_dataset = db.get(DatasetV2, dataset_id)
|
39
|
-
if len(db_dataset.history) == 0:
|
40
|
-
logger.warning(
|
41
|
-
f"History for {dataset_id=} is empty. Likely reason: the job "
|
42
|
-
"failed before its first task was marked as SUBMITTED. "
|
43
|
-
"Continue."
|
44
|
-
)
|
45
|
-
return
|
46
|
-
workflowtask_id = db_dataset.history[-1]["workflowtask"]["id"]
|
47
|
-
last_item_status = db_dataset.history[-1]["status"]
|
48
|
-
if last_item_status != WorkflowTaskStatusTypeV2.SUBMITTED:
|
49
|
-
logger.warning(
|
50
|
-
"Unexpected branch: "
|
51
|
-
f"Last history item, for {workflowtask_id=}, "
|
52
|
-
f"has status {last_item_status}. Skip."
|
53
|
-
)
|
54
|
-
return
|
55
|
-
logger.info(f"Setting history item for {workflowtask_id=} to failed.")
|
56
|
-
db_dataset.history[-1]["status"] = WorkflowTaskStatusTypeV2.FAILED
|
57
|
-
flag_modified(db_dataset, "history")
|
58
|
-
db.merge(db_dataset)
|
59
|
-
db.commit()
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|