scalable-pypeline 2.1.25__tar.gz → 2.1.27__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.
Potentially problematic release.
This version of scalable-pypeline might be problematic. Click here for more details.
- {scalable-pypeline-2.1.25/scalable_pypeline.egg-info → scalable-pypeline-2.1.27}/PKG-INFO +1 -1
- scalable-pypeline-2.1.27/pypeline/__init__.py +1 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/pipeline_settings_schema.py +1 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/pipelines/composition/parallel_pipeline_composition.py +29 -2
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/pipelines/middleware/pypeline_middleware.py +12 -4
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27/scalable_pypeline.egg-info}/PKG-INFO +1 -1
- scalable-pypeline-2.1.25/pypeline/__init__.py +0 -1
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/LICENSE +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/MANIFEST.in +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/README.md +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/barrier.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/constants.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/dramatiq.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/executable_job_config_schema.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/extensions.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/flask/__init__.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/flask/api/__init__.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/flask/api/pipelines.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/flask/api/schedules.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/flask/decorators.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/flask/flask_pypeline.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/pipeline_config_schema.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/pipelines/__init__.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/pipelines/composition/__init__.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/pipelines/composition/pypeline_composition.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/pipelines/factory.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/pipelines/middleware/__init__.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/pipelines/middleware/get_active_worker_id_middleware.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/pipelines/middleware/graceful_shutdown_middleware.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/pipelines/middleware/parallel_pipeline_middleware.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/pypeline_yaml.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/schedule_config_schema.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/utils/__init__.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/utils/config_utils.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/utils/dramatiq_utils.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/utils/executable_job_util.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/utils/graceful_shutdown_util.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/utils/module_utils.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/utils/pipeline_utils.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/utils/schema_utils.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/requirements.txt +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/scalable_pypeline.egg-info/SOURCES.txt +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/scalable_pypeline.egg-info/dependency_links.txt +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/scalable_pypeline.egg-info/entry_points.txt +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/scalable_pypeline.egg-info/requires.txt +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/scalable_pypeline.egg-info/top_level.txt +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/setup.cfg +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/setup.py +0 -0
- {scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/tests/fixtures/__init__.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.1.27"
|
|
@@ -465,6 +465,7 @@ class PipelineScenarioSchema(Schema):
|
|
|
465
465
|
"produce alternative calculations and or results."
|
|
466
466
|
},
|
|
467
467
|
)
|
|
468
|
+
execution_id = fields.String(required=False, metadata={"description":"Execution id for a known scenario"})
|
|
468
469
|
|
|
469
470
|
|
|
470
471
|
class PipelineScenariosSchema(Schema):
|
|
@@ -5,12 +5,22 @@ import json
|
|
|
5
5
|
import time
|
|
6
6
|
import typing
|
|
7
7
|
from uuid import uuid4
|
|
8
|
+
from urllib.parse import urlparse
|
|
8
9
|
|
|
9
10
|
from dramatiq.broker import get_broker
|
|
10
11
|
from dramatiq.results import ResultMissing
|
|
11
12
|
from db_medley.redis_conf import RedisConnector
|
|
12
13
|
from redis.exceptions import RedisError
|
|
13
|
-
|
|
14
|
+
from redis.sentinel import Sentinel
|
|
15
|
+
from pypeline.constants import (
|
|
16
|
+
REDIS_URL,
|
|
17
|
+
REDIS_SENTINEL_MASTER_NAME,
|
|
18
|
+
DEFAULT_REDIS_SOCKET_CONNECT_TIMEOUT,
|
|
19
|
+
DEFAULT_REDIS_SOCKET_TIMEOUT,
|
|
20
|
+
DEFAULT_REDIS_RETRY_ON_TIMEOUT,
|
|
21
|
+
DEFAULT_REDIS_SOCKET_KEEPALIVE,
|
|
22
|
+
DEFAULT_REDIS_HEALTH_CHECK_INTERVAL,
|
|
23
|
+
)
|
|
14
24
|
from pypeline.barrier import LockingParallelBarrier
|
|
15
25
|
from pypeline.constants import DEFAULT_RESULT_TTL
|
|
16
26
|
from pypeline.dramatiq import REDIS_URL
|
|
@@ -240,9 +250,26 @@ class PipelineResult:
|
|
|
240
250
|
self.pipeline: parallel_pipeline = None
|
|
241
251
|
self.execution_id = execution_id
|
|
242
252
|
self.redis_key = f"{execution_id}-results-key"
|
|
243
|
-
self.redis_conn = RedisConnector().get_connection()
|
|
244
253
|
self.result_ttl = result_ttl
|
|
245
254
|
|
|
255
|
+
if REDIS_SENTINEL_MASTER_NAME is not None:
|
|
256
|
+
parsed_redis_url = urlparse(REDIS_URL)
|
|
257
|
+
redis_sentinel = Sentinel(
|
|
258
|
+
sentinels=[(parsed_redis_url.hostname, parsed_redis_url.port)],
|
|
259
|
+
)
|
|
260
|
+
self.redis_conn = redis_sentinel.master_for(
|
|
261
|
+
REDIS_SENTINEL_MASTER_NAME,
|
|
262
|
+
db=int(parsed_redis_url.path[1]) if parsed_redis_url.path else 0,
|
|
263
|
+
password=parsed_redis_url.password,
|
|
264
|
+
socket_connect_timeout=DEFAULT_REDIS_SOCKET_CONNECT_TIMEOUT,
|
|
265
|
+
socket_timeout=DEFAULT_REDIS_SOCKET_TIMEOUT,
|
|
266
|
+
retry_on_timeout=DEFAULT_REDIS_RETRY_ON_TIMEOUT,
|
|
267
|
+
socket_keepalive=DEFAULT_REDIS_SOCKET_KEEPALIVE,
|
|
268
|
+
health_check_interval=DEFAULT_REDIS_HEALTH_CHECK_INTERVAL,
|
|
269
|
+
)
|
|
270
|
+
else:
|
|
271
|
+
self.redis_conn = RedisConnector().get_connection()
|
|
272
|
+
|
|
246
273
|
def create_result_entry(self, pipeline_json_str: str):
|
|
247
274
|
"""
|
|
248
275
|
Store the serialized pipeline data in Redis with a specified TTL.
|
|
@@ -76,7 +76,13 @@ class PypelineMiddleware(Middleware):
|
|
|
76
76
|
# If the lock didn't exist for the current tasks execution id then it would indicate
|
|
77
77
|
# that this is the start of a new scenario. Therefore we need to find the ancestor
|
|
78
78
|
# that is executed in the base case execution id and make sure it has completed
|
|
79
|
-
|
|
79
|
+
tasks_to_run_in_scenario = None
|
|
80
|
+
|
|
81
|
+
for scenario in message.options["scenarios"]:
|
|
82
|
+
if scenario["execution_id"] == execution_id:
|
|
83
|
+
tasks_to_run_in_scenario = scenario["tasksToRunInScenario"]
|
|
84
|
+
|
|
85
|
+
if ancestor not in tasks_to_run_in_scenario and remaining_tasks is None:
|
|
80
86
|
ancestor_task_key = (
|
|
81
87
|
f"{message.options['base_case_execution_id']}-{ancestor}"
|
|
82
88
|
)
|
|
@@ -95,15 +101,17 @@ class PypelineMiddleware(Middleware):
|
|
|
95
101
|
remaining_tasks = locking_parallel_barrier.get_task_count()
|
|
96
102
|
finally:
|
|
97
103
|
locking_parallel_barrier.release_lock()
|
|
104
|
+
|
|
105
|
+
|
|
98
106
|
if remaining_tasks is None or remaining_tasks >= 1:
|
|
99
107
|
ancestor_tasks_complete = False
|
|
100
108
|
break
|
|
101
109
|
|
|
102
110
|
# If the child's ancestor tasks aren't complete move onto the next child to check
|
|
103
111
|
if not ancestor_tasks_complete:
|
|
104
|
-
|
|
112
|
+
continue
|
|
105
113
|
|
|
106
|
-
# Handle situation where base case kicks off new scenario
|
|
114
|
+
# Handle situation where base case kicks off new scenario.
|
|
107
115
|
if (
|
|
108
116
|
message.options["base_case_execution_id"]
|
|
109
117
|
== message.options["execution_id"]
|
|
@@ -160,7 +168,7 @@ class PypelineMiddleware(Middleware):
|
|
|
160
168
|
)
|
|
161
169
|
messages.append(scenario_message)
|
|
162
170
|
|
|
163
|
-
#
|
|
171
|
+
# If we've made it here all ancestors of this child are complete and it's time to run.
|
|
164
172
|
task_key = f"{execution_id}-{child}"
|
|
165
173
|
locking_parallel_barrier = LockingParallelBarrier(
|
|
166
174
|
self.redis_url,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2.1.25"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/executable_job_config_schema.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
|
{scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/pipelines/composition/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/pipelines/middleware/__init__.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
|
{scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/pypeline/utils/graceful_shutdown_util.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/scalable_pypeline.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/scalable_pypeline.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/scalable_pypeline.egg-info/requires.txt
RENAMED
|
File without changes
|
{scalable-pypeline-2.1.25 → scalable-pypeline-2.1.27}/scalable_pypeline.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|