apache-airflow-providers-edge3 1.1.2rc2__tar.gz → 1.1.3rc1__tar.gz
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.
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/PKG-INFO +6 -6
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/README.rst +3 -3
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/changelog.rst +12 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/index.rst +1 -1
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/provider.yaml +2 -1
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/pyproject.toml +3 -3
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/__init__.py +1 -1
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/example_dags/win_test.py +1 -1
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/executors/edge_executor.py +52 -12
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/tests/unit/edge3/executors/test_edge_executor.py +97 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/architecture.rst +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/cli-ref.rst +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/commits.rst +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/conf.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/configurations-ref.rst +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/deployment.rst +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/edge_executor.rst +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/img/distributed_architecture.svg +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/img/edge_package.svg +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/img/worker_hosts.png +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/img/worker_maintenance.png +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/install_on_windows.rst +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/installing-providers-from-sources.rst +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/security.rst +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/ui_plugin.rst +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/why_edge.rst +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/__init__.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/__init__.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/LICENSE +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/cli/__init__.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/cli/api_client.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/cli/dataclasses.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/cli/edge_command.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/cli/signalling.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/cli/worker.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/example_dags/__init__.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/example_dags/integration_test.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/example_dags/win_notepad.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/executors/__init__.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/get_provider_info.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/models/__init__.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/models/edge_job.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/models/edge_logs.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/models/edge_worker.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/openapi/__init__.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/openapi/edge_worker_api_v1.yaml +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/plugins/__init__.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/plugins/edge_executor_plugin.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/plugins/templates/edge_worker_hosts.html +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/plugins/templates/edge_worker_jobs.html +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/version_compat.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/worker_api/__init__.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/worker_api/app.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/worker_api/auth.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/worker_api/datamodels.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/worker_api/routes/__init__.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/worker_api/routes/_v2_compat.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/worker_api/routes/_v2_routes.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/worker_api/routes/health.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/worker_api/routes/jobs.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/worker_api/routes/logs.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/src/airflow/providers/edge3/worker_api/routes/worker.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/tests/conftest.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/tests/unit/__init__.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/tests/unit/edge3/__init__.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/tests/unit/edge3/cli/__init__.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/tests/unit/edge3/cli/test_api_client.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/tests/unit/edge3/cli/test_dataclasses.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/tests/unit/edge3/cli/test_edge_command.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/tests/unit/edge3/cli/test_signalling.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/tests/unit/edge3/cli/test_worker.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/tests/unit/edge3/executors/__init__.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/tests/unit/edge3/models/__init__.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/tests/unit/edge3/plugins/__init__.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/tests/unit/edge3/plugins/test_edge_executor_plugin.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/tests/unit/edge3/worker_api/__init__.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/tests/unit/edge3/worker_api/routes/__init__.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/tests/unit/edge3/worker_api/routes/test_health.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/tests/unit/edge3/worker_api/routes/test_jobs.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/tests/unit/edge3/worker_api/routes/test_logs.py +0 -0
- {apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/tests/unit/edge3/worker_api/routes/test_worker.py +0 -0
{apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/PKG-INFO
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: apache-airflow-providers-edge3
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.3rc1
|
4
4
|
Summary: Provider package apache-airflow-providers-edge3 for Apache Airflow
|
5
5
|
Keywords: airflow-provider,edge3,airflow,integration
|
6
6
|
Author-email: Apache Software Foundation <dev@airflow.apache.org>
|
@@ -24,8 +24,8 @@ Requires-Dist: apache-airflow>=2.10.0rc1
|
|
24
24
|
Requires-Dist: pydantic>=2.11.0
|
25
25
|
Requires-Dist: retryhttp>=1.2.0,!=1.3.0
|
26
26
|
Project-URL: Bug Tracker, https://github.com/apache/airflow/issues
|
27
|
-
Project-URL: Changelog, https://airflow.staged.apache.org/docs/apache-airflow-providers-edge3/1.1.
|
28
|
-
Project-URL: Documentation, https://airflow.staged.apache.org/docs/apache-airflow-providers-edge3/1.1.
|
27
|
+
Project-URL: Changelog, https://airflow.staged.apache.org/docs/apache-airflow-providers-edge3/1.1.3/changelog.html
|
28
|
+
Project-URL: Documentation, https://airflow.staged.apache.org/docs/apache-airflow-providers-edge3/1.1.3
|
29
29
|
Project-URL: Mastodon, https://fosstodon.org/@airflow
|
30
30
|
Project-URL: Slack Chat, https://s.apache.org/airflow-slack
|
31
31
|
Project-URL: Source Code, https://github.com/apache/airflow
|
@@ -56,7 +56,7 @@ Project-URL: YouTube, https://www.youtube.com/channel/UCSXwxpWZQ7XZ1WL3wqevChA/
|
|
56
56
|
|
57
57
|
Package ``apache-airflow-providers-edge3``
|
58
58
|
|
59
|
-
Release: ``1.1.
|
59
|
+
Release: ``1.1.3``
|
60
60
|
|
61
61
|
Release Date: ``|PypiReleaseDate|``
|
62
62
|
|
@@ -82,7 +82,7 @@ This is a provider package for ``edge3`` provider. All classes for this provider
|
|
82
82
|
are in ``airflow.providers.edge3`` python package.
|
83
83
|
|
84
84
|
You can find package information and changelog for the provider
|
85
|
-
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-edge3/1.1.
|
85
|
+
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-edge3/1.1.3/>`_.
|
86
86
|
|
87
87
|
Installation
|
88
88
|
------------
|
@@ -105,5 +105,5 @@ PIP package Version required
|
|
105
105
|
================== ===================
|
106
106
|
|
107
107
|
The changelog for the provider package can be found in the
|
108
|
-
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-edge3/1.1.
|
108
|
+
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-edge3/1.1.3/changelog.html>`_.
|
109
109
|
|
{apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/README.rst
RENAMED
@@ -23,7 +23,7 @@
|
|
23
23
|
|
24
24
|
Package ``apache-airflow-providers-edge3``
|
25
25
|
|
26
|
-
Release: ``1.1.
|
26
|
+
Release: ``1.1.3``
|
27
27
|
|
28
28
|
Release Date: ``|PypiReleaseDate|``
|
29
29
|
|
@@ -49,7 +49,7 @@ This is a provider package for ``edge3`` provider. All classes for this provider
|
|
49
49
|
are in ``airflow.providers.edge3`` python package.
|
50
50
|
|
51
51
|
You can find package information and changelog for the provider
|
52
|
-
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-edge3/1.1.
|
52
|
+
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-edge3/1.1.3/>`_.
|
53
53
|
|
54
54
|
Installation
|
55
55
|
------------
|
@@ -72,4 +72,4 @@ PIP package Version required
|
|
72
72
|
================== ===================
|
73
73
|
|
74
74
|
The changelog for the provider package can be found in the
|
75
|
-
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-edge3/1.1.
|
75
|
+
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-edge3/1.1.3/changelog.html>`_.
|
@@ -27,6 +27,18 @@
|
|
27
27
|
Changelog
|
28
28
|
---------
|
29
29
|
|
30
|
+
1.1.3
|
31
|
+
.....
|
32
|
+
|
33
|
+
Bug Fixes
|
34
|
+
~~~~~~~~~
|
35
|
+
|
36
|
+
* ``Fix: Prevent duplicate edge_job insertions for deferrable tasks in EdgeExecutor (#53610) (#53927)``
|
37
|
+
|
38
|
+
.. Below changes are excluded from the changelog. Move them to
|
39
|
+
appropriate section above if needed. Do not delete the lines(!):
|
40
|
+
* ``Remove parameter from Edge example (#53997)``
|
41
|
+
|
30
42
|
1.1.2
|
31
43
|
.....
|
32
44
|
|
{apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/provider.yaml
RENAMED
@@ -33,13 +33,14 @@ description: |
|
|
33
33
|
are provided by the API server.
|
34
34
|
|
35
35
|
state: ready
|
36
|
-
source-date-epoch:
|
36
|
+
source-date-epoch: 1754503142
|
37
37
|
|
38
38
|
# Note that those versions are maintained by release manager - do not update them manually
|
39
39
|
# with the exception of case where other provider in sources has >= new provider version.
|
40
40
|
# In such case adding >= NEW_VERSION and bumping to NEW_VERSION in a provider have
|
41
41
|
# to be done in the same PR
|
42
42
|
versions:
|
43
|
+
- 1.1.3
|
43
44
|
- 1.1.2
|
44
45
|
- 1.1.1
|
45
46
|
- 1.1.0
|
{apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/pyproject.toml
RENAMED
@@ -25,7 +25,7 @@ build-backend = "flit_core.buildapi"
|
|
25
25
|
|
26
26
|
[project]
|
27
27
|
name = "apache-airflow-providers-edge3"
|
28
|
-
version = "1.1.
|
28
|
+
version = "1.1.3rc1"
|
29
29
|
description = "Provider package apache-airflow-providers-edge3 for Apache Airflow"
|
30
30
|
readme = "README.rst"
|
31
31
|
authors = [
|
@@ -96,8 +96,8 @@ apache-airflow-providers-common-sql = {workspace = true}
|
|
96
96
|
apache-airflow-providers-standard = {workspace = true}
|
97
97
|
|
98
98
|
[project.urls]
|
99
|
-
"Documentation" = "https://airflow.staged.apache.org/docs/apache-airflow-providers-edge3/1.1.
|
100
|
-
"Changelog" = "https://airflow.staged.apache.org/docs/apache-airflow-providers-edge3/1.1.
|
99
|
+
"Documentation" = "https://airflow.staged.apache.org/docs/apache-airflow-providers-edge3/1.1.3"
|
100
|
+
"Changelog" = "https://airflow.staged.apache.org/docs/apache-airflow-providers-edge3/1.1.3/changelog.html"
|
101
101
|
"Bug Tracker" = "https://github.com/apache/airflow/issues"
|
102
102
|
"Source Code" = "https://github.com/apache/airflow"
|
103
103
|
"Slack Chat" = "https://s.apache.org/airflow-slack"
|
@@ -29,7 +29,7 @@ from airflow import __version__ as airflow_version
|
|
29
29
|
|
30
30
|
__all__ = ["__version__"]
|
31
31
|
|
32
|
-
__version__ = "1.1.
|
32
|
+
__version__ = "1.1.3"
|
33
33
|
|
34
34
|
if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
|
35
35
|
"2.10.0"
|
@@ -301,7 +301,7 @@ with DAG(
|
|
301
301
|
except AirflowNotFoundException:
|
302
302
|
print("Connection 'integration_test' not found... but also OK.")
|
303
303
|
|
304
|
-
command = CmdOperator(task_id="command", command="echo
|
304
|
+
command = CmdOperator(task_id="command", command="echo Hello World")
|
305
305
|
|
306
306
|
def python_call():
|
307
307
|
print("Hello world")
|
@@ -140,20 +140,40 @@ class EdgeExecutor(BaseExecutor):
|
|
140
140
|
del self.edge_queued_tasks[key]
|
141
141
|
|
142
142
|
self.validate_airflow_tasks_run_command(command) # type: ignore[attr-defined]
|
143
|
-
|
144
|
-
|
143
|
+
|
144
|
+
# Check if job already exists with same dag_id, task_id, run_id, map_index, try_number
|
145
|
+
existing_job = (
|
146
|
+
session.query(EdgeJobModel)
|
147
|
+
.filter_by(
|
145
148
|
dag_id=key.dag_id,
|
146
149
|
task_id=key.task_id,
|
147
150
|
run_id=key.run_id,
|
148
151
|
map_index=key.map_index,
|
149
152
|
try_number=key.try_number,
|
150
|
-
state=TaskInstanceState.QUEUED,
|
151
|
-
queue=queue or DEFAULT_QUEUE,
|
152
|
-
concurrency_slots=task_instance.pool_slots,
|
153
|
-
command=str(command),
|
154
153
|
)
|
154
|
+
.first()
|
155
155
|
)
|
156
156
|
|
157
|
+
if existing_job:
|
158
|
+
existing_job.state = TaskInstanceState.QUEUED
|
159
|
+
existing_job.queue = queue or DEFAULT_QUEUE
|
160
|
+
existing_job.concurrency_slots = task_instance.pool_slots
|
161
|
+
existing_job.command = str(command)
|
162
|
+
else:
|
163
|
+
session.add(
|
164
|
+
EdgeJobModel(
|
165
|
+
dag_id=key.dag_id,
|
166
|
+
task_id=key.task_id,
|
167
|
+
run_id=key.run_id,
|
168
|
+
map_index=key.map_index,
|
169
|
+
try_number=key.try_number,
|
170
|
+
state=TaskInstanceState.QUEUED,
|
171
|
+
queue=queue or DEFAULT_QUEUE,
|
172
|
+
concurrency_slots=task_instance.pool_slots,
|
173
|
+
command=str(command),
|
174
|
+
)
|
175
|
+
)
|
176
|
+
|
157
177
|
@provide_session
|
158
178
|
def queue_workload(
|
159
179
|
self,
|
@@ -168,20 +188,40 @@ class EdgeExecutor(BaseExecutor):
|
|
168
188
|
|
169
189
|
task_instance = workload.ti
|
170
190
|
key = task_instance.key
|
171
|
-
|
172
|
-
|
191
|
+
|
192
|
+
# Check if job already exists with same dag_id, task_id, run_id, map_index, try_number
|
193
|
+
existing_job = (
|
194
|
+
session.query(EdgeJobModel)
|
195
|
+
.filter_by(
|
173
196
|
dag_id=key.dag_id,
|
174
197
|
task_id=key.task_id,
|
175
198
|
run_id=key.run_id,
|
176
199
|
map_index=key.map_index,
|
177
200
|
try_number=key.try_number,
|
178
|
-
state=TaskInstanceState.QUEUED,
|
179
|
-
queue=task_instance.queue,
|
180
|
-
concurrency_slots=task_instance.pool_slots,
|
181
|
-
command=workload.model_dump_json(),
|
182
201
|
)
|
202
|
+
.first()
|
183
203
|
)
|
184
204
|
|
205
|
+
if existing_job:
|
206
|
+
existing_job.state = TaskInstanceState.QUEUED
|
207
|
+
existing_job.queue = task_instance.queue
|
208
|
+
existing_job.concurrency_slots = task_instance.pool_slots
|
209
|
+
existing_job.command = workload.model_dump_json()
|
210
|
+
else:
|
211
|
+
session.add(
|
212
|
+
EdgeJobModel(
|
213
|
+
dag_id=key.dag_id,
|
214
|
+
task_id=key.task_id,
|
215
|
+
run_id=key.run_id,
|
216
|
+
map_index=key.map_index,
|
217
|
+
try_number=key.try_number,
|
218
|
+
state=TaskInstanceState.QUEUED,
|
219
|
+
queue=task_instance.queue,
|
220
|
+
concurrency_slots=task_instance.pool_slots,
|
221
|
+
command=workload.model_dump_json(),
|
222
|
+
)
|
223
|
+
)
|
224
|
+
|
185
225
|
def _check_worker_liveness(self, session: Session) -> bool:
|
186
226
|
"""Reset worker state if heartbeat timed out."""
|
187
227
|
changed = False
|
@@ -247,6 +247,11 @@ class TestEdgeExecutor:
|
|
247
247
|
|
248
248
|
# Prepare some data
|
249
249
|
with create_session() as session:
|
250
|
+
# Clear existing workers to avoid unique constraint violation
|
251
|
+
session.query(EdgeWorkerModel).delete()
|
252
|
+
session.commit()
|
253
|
+
|
254
|
+
# Add workers with different states
|
250
255
|
for worker_name, state, last_heartbeat in [
|
251
256
|
(
|
252
257
|
"inactive_timed_out_worker",
|
@@ -338,3 +343,95 @@ class TestEdgeExecutor:
|
|
338
343
|
with create_session() as session:
|
339
344
|
jobs = session.query(EdgeJobModel).all()
|
340
345
|
assert len(jobs) == 1
|
346
|
+
|
347
|
+
@pytest.mark.skipif(AIRFLOW_V_3_0_PLUS, reason="API only available in Airflow <3.0")
|
348
|
+
def test_execute_async_updates_existing_job(self):
|
349
|
+
executor, key = self.get_test_executor()
|
350
|
+
|
351
|
+
# First insert a job with the same key
|
352
|
+
with create_session() as session:
|
353
|
+
session.add(
|
354
|
+
EdgeJobModel(
|
355
|
+
dag_id=key.dag_id,
|
356
|
+
run_id=key.run_id,
|
357
|
+
task_id=key.task_id,
|
358
|
+
map_index=key.map_index,
|
359
|
+
try_number=key.try_number,
|
360
|
+
state=TaskInstanceState.SCHEDULED,
|
361
|
+
queue="default",
|
362
|
+
concurrency_slots=1,
|
363
|
+
command="old-command",
|
364
|
+
last_update=timezone.utcnow(),
|
365
|
+
)
|
366
|
+
)
|
367
|
+
session.commit()
|
368
|
+
|
369
|
+
# Trigger execute_async which should update the existing job
|
370
|
+
executor.edge_queued_tasks = deepcopy(executor.queued_tasks)
|
371
|
+
executor.execute_async(key=key, command=["airflow", "tasks", "run", "new", "command"])
|
372
|
+
|
373
|
+
with create_session() as session:
|
374
|
+
jobs = session.query(EdgeJobModel).all()
|
375
|
+
assert len(jobs) == 1
|
376
|
+
job = jobs[0]
|
377
|
+
assert job.state == TaskInstanceState.QUEUED
|
378
|
+
assert job.command != "old-command"
|
379
|
+
assert "new" in job.command
|
380
|
+
|
381
|
+
@pytest.mark.skipif(not AIRFLOW_V_3_0_PLUS, reason="API only available in Airflow 3.0+")
|
382
|
+
def test_queue_workload_updates_existing_job(self):
|
383
|
+
from uuid import uuid4
|
384
|
+
|
385
|
+
from airflow.executors.workloads import ExecuteTask, TaskInstance
|
386
|
+
|
387
|
+
executor = self.get_test_executor()[0]
|
388
|
+
|
389
|
+
key = TaskInstanceKey(dag_id="mock", run_id="mock", task_id="mock", map_index=-1, try_number=1)
|
390
|
+
|
391
|
+
# Insert an existing job
|
392
|
+
with create_session() as session:
|
393
|
+
session.add(
|
394
|
+
EdgeJobModel(
|
395
|
+
dag_id=key.dag_id,
|
396
|
+
task_id=key.task_id,
|
397
|
+
run_id=key.run_id,
|
398
|
+
map_index=key.map_index,
|
399
|
+
try_number=key.try_number,
|
400
|
+
state=TaskInstanceState.SCHEDULED,
|
401
|
+
queue="default",
|
402
|
+
command="old-command",
|
403
|
+
concurrency_slots=1,
|
404
|
+
last_update=timezone.utcnow(),
|
405
|
+
)
|
406
|
+
)
|
407
|
+
session.commit()
|
408
|
+
|
409
|
+
# Queue a workload with same key
|
410
|
+
workload = ExecuteTask(
|
411
|
+
token="mock",
|
412
|
+
ti=TaskInstance(
|
413
|
+
id=uuid4(),
|
414
|
+
task_id=key.task_id,
|
415
|
+
dag_id=key.dag_id,
|
416
|
+
run_id=key.run_id,
|
417
|
+
try_number=key.try_number,
|
418
|
+
map_index=key.map_index,
|
419
|
+
pool_slots=1,
|
420
|
+
queue="updated-queue",
|
421
|
+
priority_weight=1,
|
422
|
+
start_date=timezone.utcnow(),
|
423
|
+
dag_version_id=uuid4(),
|
424
|
+
),
|
425
|
+
dag_rel_path="mock.py",
|
426
|
+
log_path="mock.log",
|
427
|
+
bundle_info={"name": "n/a", "version": "no matter"},
|
428
|
+
)
|
429
|
+
|
430
|
+
executor.queue_workload(workload=workload)
|
431
|
+
|
432
|
+
with create_session() as session:
|
433
|
+
jobs = session.query(EdgeJobModel).all()
|
434
|
+
assert len(jobs) == 1
|
435
|
+
job = jobs[0]
|
436
|
+
assert job.queue == "updated-queue"
|
437
|
+
assert job.command != "old-command"
|
File without changes
|
{apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/cli-ref.rst
RENAMED
File without changes
|
{apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/commits.rst
RENAMED
File without changes
|
{apache_airflow_providers_edge3-1.1.2rc2 → apache_airflow_providers_edge3-1.1.3rc1}/docs/conf.py
RENAMED
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
|
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
|
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
|
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
|
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
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|