dagster-cloud 1.8.2__py3-none-any.whl → 1.12.6__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.
- dagster_cloud/__init__.py +3 -3
- dagster_cloud/agent/__init__.py +4 -4
- dagster_cloud/agent/cli/__init__.py +56 -17
- dagster_cloud/agent/dagster_cloud_agent.py +360 -172
- dagster_cloud/agent/instrumentation/__init__.py +0 -0
- dagster_cloud/agent/instrumentation/constants.py +2 -0
- dagster_cloud/agent/instrumentation/run_launch.py +23 -0
- dagster_cloud/agent/instrumentation/schedule.py +34 -0
- dagster_cloud/agent/instrumentation/sensor.py +34 -0
- dagster_cloud/anomaly_detection/__init__.py +2 -2
- dagster_cloud/anomaly_detection/defs.py +17 -12
- dagster_cloud/anomaly_detection/types.py +3 -3
- dagster_cloud/api/dagster_cloud_api.py +209 -293
- dagster_cloud/auth/constants.py +21 -5
- dagster_cloud/batching/__init__.py +1 -0
- dagster_cloud/batching/batcher.py +210 -0
- dagster_cloud/dagster_insights/__init__.py +12 -6
- dagster_cloud/dagster_insights/bigquery/bigquery_utils.py +3 -2
- dagster_cloud/dagster_insights/bigquery/dbt_wrapper.py +39 -12
- dagster_cloud/dagster_insights/bigquery/insights_bigquery_resource.py +8 -6
- dagster_cloud/dagster_insights/insights_utils.py +18 -8
- dagster_cloud/dagster_insights/metrics_utils.py +12 -12
- dagster_cloud/dagster_insights/snowflake/dagster_snowflake_insights.py +5 -12
- dagster_cloud/dagster_insights/snowflake/dbt_wrapper.py +34 -8
- dagster_cloud/dagster_insights/snowflake/definitions.py +38 -12
- dagster_cloud/dagster_insights/snowflake/insights_snowflake_resource.py +11 -23
- dagster_cloud/definitions/__init__.py +0 -0
- dagster_cloud/definitions/job_selection.py +36 -0
- dagster_cloud/execution/cloud_run_launcher/k8s.py +1 -1
- dagster_cloud/execution/cloud_run_launcher/process.py +3 -3
- dagster_cloud/execution/monitoring/__init__.py +27 -33
- dagster_cloud/execution/utils/process.py +3 -3
- dagster_cloud/instance/__init__.py +125 -38
- dagster_cloud/instrumentation/__init__.py +32 -0
- dagster_cloud/metadata/source_code.py +13 -8
- dagster_cloud/metrics/__init__.py +0 -0
- dagster_cloud/metrics/tracer.py +59 -0
- dagster_cloud/opentelemetry/__init__.py +0 -0
- dagster_cloud/opentelemetry/config/__init__.py +73 -0
- dagster_cloud/opentelemetry/config/exporter.py +81 -0
- dagster_cloud/opentelemetry/config/log_record_processor.py +40 -0
- dagster_cloud/opentelemetry/config/logging_handler.py +14 -0
- dagster_cloud/opentelemetry/config/meter_provider.py +9 -0
- dagster_cloud/opentelemetry/config/metric_reader.py +39 -0
- dagster_cloud/opentelemetry/controller.py +319 -0
- dagster_cloud/opentelemetry/enum.py +58 -0
- dagster_cloud/opentelemetry/factories/__init__.py +1 -0
- dagster_cloud/opentelemetry/factories/logs.py +113 -0
- dagster_cloud/opentelemetry/factories/metrics.py +121 -0
- dagster_cloud/opentelemetry/metrics/__init__.py +0 -0
- dagster_cloud/opentelemetry/metrics/meter.py +140 -0
- dagster_cloud/opentelemetry/observers/__init__.py +0 -0
- dagster_cloud/opentelemetry/observers/dagster_exception_handler.py +40 -0
- dagster_cloud/opentelemetry/observers/execution_observer.py +178 -0
- dagster_cloud/pex/grpc/__generated__/multi_pex_api_pb2.pyi +175 -0
- dagster_cloud/pex/grpc/__init__.py +2 -2
- dagster_cloud/pex/grpc/client.py +4 -4
- dagster_cloud/pex/grpc/compile.py +2 -2
- dagster_cloud/pex/grpc/server/__init__.py +2 -2
- dagster_cloud/pex/grpc/server/cli/__init__.py +31 -19
- dagster_cloud/pex/grpc/server/manager.py +60 -42
- dagster_cloud/pex/grpc/server/registry.py +28 -21
- dagster_cloud/pex/grpc/server/server.py +23 -14
- dagster_cloud/pex/grpc/types.py +5 -5
- dagster_cloud/py.typed +0 -0
- dagster_cloud/secrets/__init__.py +1 -1
- dagster_cloud/secrets/loader.py +3 -3
- dagster_cloud/serverless/__init__.py +1 -1
- dagster_cloud/serverless/io_manager.py +36 -53
- dagster_cloud/storage/client.py +54 -17
- dagster_cloud/storage/compute_logs/__init__.py +3 -1
- dagster_cloud/storage/compute_logs/compute_log_manager.py +22 -17
- dagster_cloud/storage/defs_state/__init__.py +3 -0
- dagster_cloud/storage/defs_state/queries.py +15 -0
- dagster_cloud/storage/defs_state/storage.py +113 -0
- dagster_cloud/storage/event_logs/__init__.py +3 -1
- dagster_cloud/storage/event_logs/queries.py +102 -4
- dagster_cloud/storage/event_logs/storage.py +266 -73
- dagster_cloud/storage/event_logs/utils.py +88 -7
- dagster_cloud/storage/runs/__init__.py +1 -1
- dagster_cloud/storage/runs/queries.py +17 -2
- dagster_cloud/storage/runs/storage.py +88 -42
- dagster_cloud/storage/schedules/__init__.py +1 -1
- dagster_cloud/storage/schedules/storage.py +6 -8
- dagster_cloud/storage/tags.py +66 -1
- dagster_cloud/util/__init__.py +10 -12
- dagster_cloud/util/errors.py +49 -64
- dagster_cloud/version.py +1 -1
- dagster_cloud/workspace/config_schema/__init__.py +55 -13
- dagster_cloud/workspace/docker/__init__.py +76 -25
- dagster_cloud/workspace/docker/utils.py +1 -1
- dagster_cloud/workspace/ecs/__init__.py +1 -1
- dagster_cloud/workspace/ecs/client.py +51 -33
- dagster_cloud/workspace/ecs/launcher.py +76 -22
- dagster_cloud/workspace/ecs/run_launcher.py +3 -3
- dagster_cloud/workspace/ecs/utils.py +14 -5
- dagster_cloud/workspace/kubernetes/__init__.py +1 -1
- dagster_cloud/workspace/kubernetes/launcher.py +61 -29
- dagster_cloud/workspace/kubernetes/utils.py +34 -22
- dagster_cloud/workspace/user_code_launcher/__init__.py +5 -3
- dagster_cloud/workspace/user_code_launcher/process.py +16 -14
- dagster_cloud/workspace/user_code_launcher/user_code_launcher.py +552 -172
- dagster_cloud/workspace/user_code_launcher/utils.py +105 -1
- {dagster_cloud-1.8.2.dist-info → dagster_cloud-1.12.6.dist-info}/METADATA +48 -42
- dagster_cloud-1.12.6.dist-info/RECORD +134 -0
- {dagster_cloud-1.8.2.dist-info → dagster_cloud-1.12.6.dist-info}/WHEEL +1 -1
- dagster_cloud-1.8.2.dist-info/RECORD +0 -100
- {dagster_cloud-1.8.2.dist-info → dagster_cloud-1.12.6.dist-info}/top_level.txt +0 -0
|
@@ -1,28 +1,17 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import os
|
|
3
3
|
from collections import defaultdict
|
|
4
|
+
from collections.abc import Iterable, Mapping, Sequence
|
|
5
|
+
from contextlib import contextmanager
|
|
4
6
|
from datetime import timezone
|
|
5
|
-
from typing import
|
|
6
|
-
TYPE_CHECKING,
|
|
7
|
-
Any,
|
|
8
|
-
Callable,
|
|
9
|
-
Dict,
|
|
10
|
-
Iterable,
|
|
11
|
-
List,
|
|
12
|
-
Mapping,
|
|
13
|
-
Optional,
|
|
14
|
-
Sequence,
|
|
15
|
-
Set,
|
|
16
|
-
Tuple,
|
|
17
|
-
Union,
|
|
18
|
-
cast,
|
|
19
|
-
)
|
|
7
|
+
from typing import TYPE_CHECKING, AbstractSet, Any, Callable, Optional, Union, cast # noqa: UP035
|
|
20
8
|
from uuid import uuid4
|
|
21
9
|
|
|
22
10
|
import dagster._check as check
|
|
23
|
-
from dagster import AssetCheckKey, DagsterInvalidInvocationError
|
|
11
|
+
from dagster import AssetCheckKey, DagsterInvalidInvocationError, PartitionsDefinition
|
|
24
12
|
from dagster._core.assets import AssetDetails
|
|
25
13
|
from dagster._core.definitions.events import AssetKey, ExpectationResult
|
|
14
|
+
from dagster._core.definitions.freshness import FreshnessStateRecord
|
|
26
15
|
from dagster._core.event_api import (
|
|
27
16
|
AssetRecordsFilter,
|
|
28
17
|
EventLogRecord,
|
|
@@ -34,6 +23,7 @@ from dagster._core.event_api import (
|
|
|
34
23
|
from dagster._core.events import DagsterEvent, DagsterEventType
|
|
35
24
|
from dagster._core.events.log import EventLogEntry
|
|
36
25
|
from dagster._core.execution.stats import RunStepKeyStatsSnapshot, RunStepMarker, StepEventStatus
|
|
26
|
+
from dagster._core.instance.config import PoolConfig, PoolGranularity
|
|
37
27
|
from dagster._core.storage.asset_check_execution_record import (
|
|
38
28
|
AssetCheckExecutionRecord,
|
|
39
29
|
AssetCheckExecutionRecordStatus,
|
|
@@ -46,10 +36,11 @@ from dagster._core.storage.event_log.base import (
|
|
|
46
36
|
EventLogConnection,
|
|
47
37
|
EventLogStorage,
|
|
48
38
|
PlannedMaterializationInfo,
|
|
39
|
+
PoolLimit,
|
|
49
40
|
)
|
|
50
41
|
from dagster._core.storage.partition_status_cache import AssetStatusCacheValue
|
|
42
|
+
from dagster._core.types.pagination import PaginatedResults
|
|
51
43
|
from dagster._serdes import ConfigurableClass, ConfigurableClassData, serialize_value
|
|
52
|
-
from dagster._serdes.serdes import deserialize_value
|
|
53
44
|
from dagster._time import datetime_from_timestamp
|
|
54
45
|
from dagster._utils.concurrency import (
|
|
55
46
|
ClaimedSlotInfo,
|
|
@@ -61,9 +52,11 @@ from dagster._utils.concurrency import (
|
|
|
61
52
|
from dagster._utils.error import SerializableErrorInfo
|
|
62
53
|
from dagster._utils.merger import merge_dicts
|
|
63
54
|
from dagster_cloud_cli.core.errors import DagsterCloudAgentServerError
|
|
55
|
+
from dagster_shared.serdes.serdes import deserialize_value
|
|
64
56
|
from typing_extensions import Self
|
|
65
57
|
|
|
66
58
|
from dagster_cloud.api.dagster_cloud_api import StoreEventBatchRequest
|
|
59
|
+
from dagster_cloud.metrics.tracer import Tracer
|
|
67
60
|
from dagster_cloud.storage.event_logs.utils import truncate_event
|
|
68
61
|
from dagster_cloud.util import compressed_namedtuple_upload_file
|
|
69
62
|
|
|
@@ -71,7 +64,11 @@ if TYPE_CHECKING:
|
|
|
71
64
|
from dagster_cloud.instance import DagsterCloudAgentInstance
|
|
72
65
|
|
|
73
66
|
|
|
74
|
-
|
|
67
|
+
# Guard against out of order event insertion issues by default
|
|
68
|
+
DEFAULT_RUN_SCOPED_EVENT_TAILER_OFFSET = 20000
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
from dagster_cloud.storage.event_logs.queries import (
|
|
75
72
|
ADD_DYNAMIC_PARTITIONS_MUTATION,
|
|
76
73
|
CHECK_CONCURRENCY_CLAIM_QUERY,
|
|
77
74
|
CLAIM_CONCURRENCY_SLOT_MUTATION,
|
|
@@ -79,6 +76,7 @@ from .queries import (
|
|
|
79
76
|
DELETE_DYNAMIC_PARTITION_MUTATION,
|
|
80
77
|
DELETE_EVENTS_MUTATION,
|
|
81
78
|
ENABLE_SECONDARY_INDEX_MUTATION,
|
|
79
|
+
FETCH_FAILED_MATERIALIZATIONS_QUERY,
|
|
82
80
|
FETCH_MATERIALIZATIONS_QUERY,
|
|
83
81
|
FETCH_OBSERVATIONS_QUERY,
|
|
84
82
|
FETCH_PLANNED_MATERIALIZATIONS,
|
|
@@ -87,6 +85,7 @@ from .queries import (
|
|
|
87
85
|
GET_ALL_ASSET_KEYS_QUERY,
|
|
88
86
|
GET_ASSET_CHECK_STATE_QUERY,
|
|
89
87
|
GET_ASSET_RECORDS_QUERY,
|
|
88
|
+
GET_ASSET_STATUS_CACHE_VALUES,
|
|
90
89
|
GET_CONCURRENCY_INFO_QUERY,
|
|
91
90
|
GET_CONCURRENCY_KEYS_QUERY,
|
|
92
91
|
GET_DYNAMIC_PARTITIONS_QUERY,
|
|
@@ -99,6 +98,10 @@ from .queries import (
|
|
|
99
98
|
GET_LATEST_TAGS_BY_PARTITION,
|
|
100
99
|
GET_MATERIALIZATION_COUNT_BY_PARTITION,
|
|
101
100
|
GET_MATERIALIZED_PARTITIONS,
|
|
101
|
+
GET_MAXIMUM_RECORD_ID,
|
|
102
|
+
GET_PAGINATED_DYNAMIC_PARTITIONS_QUERY,
|
|
103
|
+
GET_POOL_CONFIG_QUERY,
|
|
104
|
+
GET_POOL_LIMITS_QUERY,
|
|
102
105
|
GET_RECORDS_FOR_RUN_QUERY,
|
|
103
106
|
GET_RUN_STATUS_CHANGE_EVENTS_QUERY,
|
|
104
107
|
GET_STATS_FOR_RUN_QUERY,
|
|
@@ -116,12 +119,12 @@ from .queries import (
|
|
|
116
119
|
UPGRADE_EVENT_LOG_STORAGE_MUTATION,
|
|
117
120
|
WIPE_ASSET_CACHED_STATUS_DATA_MUTATION,
|
|
118
121
|
WIPE_ASSET_MUTATION,
|
|
122
|
+
WIPE_ASSET_PARTITIONS_MUTATION,
|
|
119
123
|
WIPE_EVENT_LOG_STORAGE_MUTATION,
|
|
120
124
|
)
|
|
121
125
|
|
|
122
126
|
|
|
123
127
|
def _input_for_event(event: EventLogEntry):
|
|
124
|
-
event = truncate_event(event)
|
|
125
128
|
return {
|
|
126
129
|
"errorInfo": _input_for_serializable_error_info(event.error_info),
|
|
127
130
|
"level": event.level,
|
|
@@ -172,7 +175,7 @@ def _input_for_dagster_event(dagster_event: Optional[DagsterEvent]):
|
|
|
172
175
|
}
|
|
173
176
|
|
|
174
177
|
|
|
175
|
-
def _event_log_entry_from_graphql(graphene_event_log_entry:
|
|
178
|
+
def _event_log_entry_from_graphql(graphene_event_log_entry: dict) -> EventLogEntry:
|
|
176
179
|
check.dict_param(graphene_event_log_entry, "graphene_event_log_entry")
|
|
177
180
|
|
|
178
181
|
return EventLogEntry(
|
|
@@ -202,7 +205,7 @@ def _event_log_entry_from_graphql(graphene_event_log_entry: Dict) -> EventLogEnt
|
|
|
202
205
|
|
|
203
206
|
def _get_event_records_filter_input(
|
|
204
207
|
event_records_filter,
|
|
205
|
-
) -> Optional[
|
|
208
|
+
) -> Optional[dict[str, Any]]:
|
|
206
209
|
check.opt_inst_param(event_records_filter, "event_records_filter", EventRecordsFilter)
|
|
207
210
|
|
|
208
211
|
if event_records_filter is None:
|
|
@@ -254,7 +257,7 @@ def _get_event_records_filter_input(
|
|
|
254
257
|
|
|
255
258
|
def _get_asset_records_filter_input(
|
|
256
259
|
records_filter: Union[AssetKey, AssetRecordsFilter],
|
|
257
|
-
) ->
|
|
260
|
+
) -> dict[str, Any]:
|
|
258
261
|
check.opt_inst_param(records_filter, "records_filter", (AssetKey, AssetRecordsFilter))
|
|
259
262
|
|
|
260
263
|
if isinstance(records_filter, AssetKey):
|
|
@@ -282,7 +285,7 @@ def _get_asset_records_filter_input(
|
|
|
282
285
|
}
|
|
283
286
|
|
|
284
287
|
|
|
285
|
-
def _fetch_run_status_changes_filter_input(records_filter) ->
|
|
288
|
+
def _fetch_run_status_changes_filter_input(records_filter) -> dict[str, Any]:
|
|
286
289
|
check.inst_param(
|
|
287
290
|
records_filter, "records_filter", (DagsterEventType, RunStatusChangeRecordsFilter)
|
|
288
291
|
)
|
|
@@ -297,10 +300,11 @@ def _fetch_run_status_changes_filter_input(records_filter) -> Dict[str, Any]:
|
|
|
297
300
|
"afterStorageId": records_filter.after_storage_id,
|
|
298
301
|
"beforeStorageId": records_filter.before_storage_id,
|
|
299
302
|
"storageIds": records_filter.storage_ids,
|
|
303
|
+
"jobNames": records_filter.job_names,
|
|
300
304
|
}
|
|
301
305
|
|
|
302
306
|
|
|
303
|
-
def _event_record_from_graphql(graphene_event_record:
|
|
307
|
+
def _event_record_from_graphql(graphene_event_record: dict) -> EventLogRecord:
|
|
304
308
|
check.dict_param(graphene_event_record, "graphene_event_record")
|
|
305
309
|
|
|
306
310
|
return EventLogRecord(
|
|
@@ -309,7 +313,7 @@ def _event_record_from_graphql(graphene_event_record: Dict) -> EventLogRecord:
|
|
|
309
313
|
)
|
|
310
314
|
|
|
311
315
|
|
|
312
|
-
def _asset_entry_from_graphql(graphene_asset_entry:
|
|
316
|
+
def _asset_entry_from_graphql(graphene_asset_entry: dict) -> AssetEntry:
|
|
313
317
|
check.dict_param(graphene_asset_entry, "graphene_asset_entry")
|
|
314
318
|
return AssetEntry(
|
|
315
319
|
asset_key=AssetKey(graphene_asset_entry["assetKey"]["path"]),
|
|
@@ -351,10 +355,14 @@ def _asset_entry_from_graphql(graphene_asset_entry: Dict) -> AssetEntry:
|
|
|
351
355
|
if graphene_asset_entry["lastObservationRecord"]
|
|
352
356
|
else None
|
|
353
357
|
),
|
|
358
|
+
last_planned_materialization_storage_id=graphene_asset_entry[
|
|
359
|
+
"lastPlannedMaterializationStorageId"
|
|
360
|
+
],
|
|
361
|
+
last_planned_materialization_run_id=graphene_asset_entry["lastPlannedMaterializationRunId"],
|
|
354
362
|
)
|
|
355
363
|
|
|
356
364
|
|
|
357
|
-
def _asset_record_from_graphql(graphene_asset_record:
|
|
365
|
+
def _asset_record_from_graphql(graphene_asset_record: dict) -> AssetRecord:
|
|
358
366
|
check.dict_param(graphene_asset_record, "graphene_asset_record")
|
|
359
367
|
return AssetRecord(
|
|
360
368
|
storage_id=graphene_asset_record["storageId"],
|
|
@@ -362,8 +370,9 @@ def _asset_record_from_graphql(graphene_asset_record: Dict) -> AssetRecord:
|
|
|
362
370
|
)
|
|
363
371
|
|
|
364
372
|
|
|
365
|
-
def _asset_check_execution_record_from_graphql(data:
|
|
373
|
+
def _asset_check_execution_record_from_graphql(data: dict, key: AssetCheckKey):
|
|
366
374
|
return AssetCheckExecutionRecord(
|
|
375
|
+
key=key,
|
|
367
376
|
id=data["id"],
|
|
368
377
|
run_id=data["runId"],
|
|
369
378
|
status=AssetCheckExecutionRecordStatus(data["status"]),
|
|
@@ -373,25 +382,36 @@ def _asset_check_execution_record_from_graphql(data: Dict):
|
|
|
373
382
|
|
|
374
383
|
|
|
375
384
|
def _asset_check_summary_record_from_graphql(
|
|
376
|
-
graphene_asset_check_summary_record:
|
|
385
|
+
graphene_asset_check_summary_record: dict,
|
|
377
386
|
) -> AssetCheckSummaryRecord:
|
|
378
387
|
check.dict_param(graphene_asset_check_summary_record, "graphene_asset_check_summary_record")
|
|
388
|
+
|
|
389
|
+
asset_check_key = AssetCheckKey.from_graphql_input(
|
|
390
|
+
graphene_asset_check_summary_record["assetCheckKey"]
|
|
391
|
+
)
|
|
379
392
|
return AssetCheckSummaryRecord(
|
|
380
|
-
asset_check_key=
|
|
381
|
-
graphene_asset_check_summary_record["assetCheckKey"]
|
|
382
|
-
),
|
|
393
|
+
asset_check_key=asset_check_key,
|
|
383
394
|
last_check_execution_record=(
|
|
384
395
|
_asset_check_execution_record_from_graphql(
|
|
385
|
-
graphene_asset_check_summary_record["lastCheckExecutionRecord"]
|
|
396
|
+
graphene_asset_check_summary_record["lastCheckExecutionRecord"],
|
|
397
|
+
asset_check_key,
|
|
386
398
|
)
|
|
387
399
|
if graphene_asset_check_summary_record["lastCheckExecutionRecord"]
|
|
388
400
|
else None
|
|
389
401
|
),
|
|
402
|
+
last_completed_check_execution_record=(
|
|
403
|
+
_asset_check_execution_record_from_graphql(
|
|
404
|
+
graphene_asset_check_summary_record["lastCompletedCheckExecutionRecord"],
|
|
405
|
+
asset_check_key,
|
|
406
|
+
)
|
|
407
|
+
if graphene_asset_check_summary_record["lastCompletedCheckExecutionRecord"]
|
|
408
|
+
else None
|
|
409
|
+
),
|
|
390
410
|
last_run_id=graphene_asset_check_summary_record["lastRunId"],
|
|
391
411
|
)
|
|
392
412
|
|
|
393
413
|
|
|
394
|
-
def _event_records_result_from_graphql(graphene_event_records_result:
|
|
414
|
+
def _event_records_result_from_graphql(graphene_event_records_result: dict) -> EventRecordsResult:
|
|
395
415
|
return EventRecordsResult(
|
|
396
416
|
records=[
|
|
397
417
|
_event_record_from_graphql(record)
|
|
@@ -402,19 +422,19 @@ def _event_records_result_from_graphql(graphene_event_records_result: Dict) -> E
|
|
|
402
422
|
)
|
|
403
423
|
|
|
404
424
|
|
|
405
|
-
def _claimed_slot_from_graphql(graphene_claimed_slot_dict:
|
|
425
|
+
def _claimed_slot_from_graphql(graphene_claimed_slot_dict: dict) -> ClaimedSlotInfo:
|
|
406
426
|
check.dict_param(graphene_claimed_slot_dict, "graphene_claimed_slot_dict")
|
|
407
427
|
return ClaimedSlotInfo(
|
|
408
|
-
graphene_claimed_slot_dict["runId"],
|
|
409
|
-
graphene_claimed_slot_dict["stepKey"],
|
|
428
|
+
run_id=graphene_claimed_slot_dict["runId"],
|
|
429
|
+
step_key=graphene_claimed_slot_dict["stepKey"],
|
|
410
430
|
)
|
|
411
431
|
|
|
412
432
|
|
|
413
|
-
def _pending_step_from_graphql(graphene_pending_step:
|
|
433
|
+
def _pending_step_from_graphql(graphene_pending_step: dict) -> PendingStepInfo:
|
|
414
434
|
check.dict_param(graphene_pending_step, "graphene_pending_step")
|
|
415
435
|
return PendingStepInfo(
|
|
416
|
-
graphene_pending_step["runId"],
|
|
417
|
-
graphene_pending_step["stepKey"],
|
|
436
|
+
run_id=graphene_pending_step["runId"],
|
|
437
|
+
step_key=graphene_pending_step["stepKey"],
|
|
418
438
|
enqueued_timestamp=datetime_from_timestamp(graphene_pending_step["enqueuedTimestamp"]),
|
|
419
439
|
assigned_timestamp=(
|
|
420
440
|
datetime_from_timestamp(graphene_pending_step["assignedTimestamp"])
|
|
@@ -432,6 +452,7 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
432
452
|
"""
|
|
433
453
|
self._inst_data = check.opt_inst_param(inst_data, "inst_data", ConfigurableClassData)
|
|
434
454
|
self._override_graphql_client = override_graphql_client
|
|
455
|
+
self._tracer = Tracer()
|
|
435
456
|
|
|
436
457
|
@property
|
|
437
458
|
def inst_data(self):
|
|
@@ -450,14 +471,12 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
450
471
|
return (
|
|
451
472
|
self._override_graphql_client
|
|
452
473
|
if self._override_graphql_client
|
|
453
|
-
else self._instance.graphql_client
|
|
474
|
+
else self._instance.graphql_client # pyright: ignore[reportAttributeAccessIssue]
|
|
454
475
|
)
|
|
455
476
|
|
|
456
477
|
@property
|
|
457
478
|
def agent_instance(self) -> "DagsterCloudAgentInstance":
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
return cast(DagsterCloudAgentInstance, self._instance)
|
|
479
|
+
return cast("DagsterCloudAgentInstance", self._instance)
|
|
461
480
|
|
|
462
481
|
def _execute_query(self, query, variables=None, headers=None, idempotent_mutation=False):
|
|
463
482
|
return self._graphql_client.execute(
|
|
@@ -467,11 +486,15 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
467
486
|
idempotent_mutation=idempotent_mutation,
|
|
468
487
|
)
|
|
469
488
|
|
|
489
|
+
def get_maximum_record_id(self) -> Optional[int]:
|
|
490
|
+
res = self._execute_query(GET_MAXIMUM_RECORD_ID)
|
|
491
|
+
return res["data"]["eventLogs"]["getMaximumRecordId"]
|
|
492
|
+
|
|
470
493
|
def get_records_for_run(
|
|
471
494
|
self,
|
|
472
495
|
run_id: str,
|
|
473
496
|
cursor: Optional[str] = None,
|
|
474
|
-
of_type: Optional[Union[DagsterEventType,
|
|
497
|
+
of_type: Optional[Union[DagsterEventType, set[DagsterEventType]]] = None,
|
|
475
498
|
limit: Optional[int] = None,
|
|
476
499
|
ascending: bool = True,
|
|
477
500
|
) -> EventLogConnection:
|
|
@@ -485,12 +508,12 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
485
508
|
"runId": check.str_param(run_id, "run_id"),
|
|
486
509
|
"cursor": check.opt_str_param(cursor, "cursor"),
|
|
487
510
|
"ofType": (
|
|
488
|
-
cast(DagsterEventType, of_type).value
|
|
511
|
+
cast("DagsterEventType", of_type).value
|
|
489
512
|
if of_type and not is_of_type_set
|
|
490
513
|
else None
|
|
491
514
|
),
|
|
492
515
|
"ofTypes": (
|
|
493
|
-
[dagster_type.value for dagster_type in cast(set, of_type)]
|
|
516
|
+
[dagster_type.value for dagster_type in cast("set", of_type)]
|
|
494
517
|
if of_type and is_of_type_set
|
|
495
518
|
else None
|
|
496
519
|
),
|
|
@@ -524,8 +547,8 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
524
547
|
)
|
|
525
548
|
|
|
526
549
|
def get_step_stats_for_run( # pyright: ignore[reportIncompatibleMethodOverride], fix me!
|
|
527
|
-
self, run_id: str, step_keys: Optional[
|
|
528
|
-
) ->
|
|
550
|
+
self, run_id: str, step_keys: Optional[list[str]] = None
|
|
551
|
+
) -> list[RunStepKeyStatsSnapshot]:
|
|
529
552
|
res = self._execute_query(
|
|
530
553
|
GET_STEP_STATS_FOR_RUN_QUERY,
|
|
531
554
|
variables={
|
|
@@ -579,24 +602,55 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
579
602
|
files={"store_events.tmp": f},
|
|
580
603
|
)
|
|
581
604
|
|
|
605
|
+
def _add_metric_header(self, headers: dict[str, str]):
|
|
606
|
+
if os.getenv("DISABLE_DAGSTER_CLOUD_STORE_EVENT_SEND_METRICS") is not None:
|
|
607
|
+
return
|
|
608
|
+
|
|
609
|
+
try:
|
|
610
|
+
span_metric = self._tracer.pop_serialized_span()
|
|
611
|
+
if span_metric:
|
|
612
|
+
headers["Dagster-Cloud-Metric"] = span_metric
|
|
613
|
+
except:
|
|
614
|
+
pass
|
|
615
|
+
|
|
616
|
+
@contextmanager
|
|
617
|
+
def _event_span(self, event: EventLogEntry):
|
|
618
|
+
if os.getenv("DISABLE_DAGSTER_CLOUD_STORE_EVENT_SEND_METRICS") is not None:
|
|
619
|
+
yield
|
|
620
|
+
else:
|
|
621
|
+
with self._tracer.start_span("store-event") as event_span:
|
|
622
|
+
event_span.set_attribute(
|
|
623
|
+
"event_type",
|
|
624
|
+
event.dagster_event.event_type_value
|
|
625
|
+
if event.dagster_event is not None
|
|
626
|
+
else "user",
|
|
627
|
+
)
|
|
628
|
+
event_span.set_attribute("run_id", event.run_id)
|
|
629
|
+
yield
|
|
630
|
+
|
|
582
631
|
def store_event(self, event: EventLogEntry):
|
|
583
632
|
check.inst_param(event, "event", EventLogEntry)
|
|
584
|
-
headers = {"Idempotency-Key": str(uuid4())}
|
|
633
|
+
headers = {"Idempotency-Key": str(uuid4()), "X-Event-Write": "true"}
|
|
585
634
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
635
|
+
self._add_metric_header(headers)
|
|
636
|
+
|
|
637
|
+
event = truncate_event(event)
|
|
638
|
+
|
|
639
|
+
with self._event_span(event):
|
|
640
|
+
if os.getenv("DAGSTER_CLOUD_STORE_EVENT_OVER_HTTP"):
|
|
641
|
+
self._store_events_http(headers, [event])
|
|
642
|
+
else:
|
|
643
|
+
self._execute_query(
|
|
644
|
+
STORE_EVENT_MUTATION,
|
|
645
|
+
variables={
|
|
646
|
+
"eventRecord": _input_for_event(event),
|
|
647
|
+
},
|
|
648
|
+
headers=headers,
|
|
649
|
+
)
|
|
596
650
|
|
|
597
651
|
def store_event_batch(self, events: Sequence[EventLogEntry]):
|
|
598
652
|
check.sequence_param(events, "events", of_type=EventLogEntry)
|
|
599
|
-
headers = {"Idempotency-Key": str(uuid4())}
|
|
653
|
+
headers = {"Idempotency-Key": str(uuid4()), "X-Event-Write": "true"}
|
|
600
654
|
|
|
601
655
|
if os.getenv("DAGSTER_CLOUD_STORE_EVENT_OVER_HTTP"):
|
|
602
656
|
self._store_events_http(headers, events)
|
|
@@ -683,6 +737,18 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
683
737
|
def asset_records_have_last_observation(self) -> bool:
|
|
684
738
|
return True
|
|
685
739
|
|
|
740
|
+
@property
|
|
741
|
+
def supports_partition_subset_in_asset_materialization_planned_events(self) -> bool:
|
|
742
|
+
return True
|
|
743
|
+
|
|
744
|
+
@property
|
|
745
|
+
def asset_records_have_last_planned_and_failed_materializations(self) -> bool:
|
|
746
|
+
return True
|
|
747
|
+
|
|
748
|
+
@property
|
|
749
|
+
def can_store_asset_failure_events(self) -> bool:
|
|
750
|
+
return True
|
|
751
|
+
|
|
686
752
|
def get_asset_check_summary_records(
|
|
687
753
|
self, asset_check_keys: Sequence[AssetCheckKey]
|
|
688
754
|
) -> Mapping[AssetCheckKey, AssetCheckSummaryRecord]:
|
|
@@ -714,6 +780,11 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
714
780
|
for result in res["data"]["eventLogs"]["getAssetRecords"]
|
|
715
781
|
]
|
|
716
782
|
|
|
783
|
+
def get_freshness_state_records(
|
|
784
|
+
self, keys: Sequence[AssetKey]
|
|
785
|
+
) -> Mapping[AssetKey, FreshnessStateRecord]:
|
|
786
|
+
raise NotImplementedError("Not callable from user cloud")
|
|
787
|
+
|
|
717
788
|
def has_asset_key(self, asset_key: AssetKey):
|
|
718
789
|
check.inst_param(asset_key, "asset_key", AssetKey)
|
|
719
790
|
|
|
@@ -770,7 +841,7 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
770
841
|
asset_key: AssetKey,
|
|
771
842
|
before_cursor: Optional[int] = None,
|
|
772
843
|
after_cursor: Optional[int] = None,
|
|
773
|
-
) ->
|
|
844
|
+
) -> set[str]:
|
|
774
845
|
check.inst_param(asset_key, "asset_key", AssetKey)
|
|
775
846
|
check.opt_int_param(before_cursor, "before_cursor")
|
|
776
847
|
check.opt_int_param(after_cursor, "after_cursor")
|
|
@@ -805,7 +876,7 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
805
876
|
"getMaterializationCountByPartition"
|
|
806
877
|
]
|
|
807
878
|
|
|
808
|
-
materialization_count_by_partition:
|
|
879
|
+
materialization_count_by_partition: dict[AssetKey, dict[str, int]] = {
|
|
809
880
|
asset_key: {} for asset_key in asset_keys
|
|
810
881
|
}
|
|
811
882
|
for asset_count in materialization_count_result:
|
|
@@ -818,17 +889,21 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
818
889
|
return materialization_count_by_partition
|
|
819
890
|
|
|
820
891
|
def get_latest_storage_id_by_partition(
|
|
821
|
-
self,
|
|
892
|
+
self,
|
|
893
|
+
asset_key: AssetKey,
|
|
894
|
+
event_type: DagsterEventType,
|
|
895
|
+
partitions: Optional[set[str]] = None,
|
|
822
896
|
) -> Mapping[str, int]:
|
|
823
897
|
res = self._execute_query(
|
|
824
898
|
GET_LATEST_STORAGE_ID_BY_PARTITION,
|
|
825
899
|
variables={
|
|
826
900
|
"assetKey": asset_key.to_string(),
|
|
827
901
|
"eventType": event_type.value,
|
|
902
|
+
"partitions": list(partitions) if partitions else None,
|
|
828
903
|
},
|
|
829
904
|
)
|
|
830
905
|
latest_storage_id_result = res["data"]["eventLogs"]["getLatestStorageIdByPartition"]
|
|
831
|
-
latest_storage_id_by_partition:
|
|
906
|
+
latest_storage_id_by_partition: dict[str, int] = {}
|
|
832
907
|
|
|
833
908
|
for graphene_latest_storage_id in latest_storage_id_result:
|
|
834
909
|
latest_storage_id_by_partition[graphene_latest_storage_id["partition"]] = (
|
|
@@ -858,7 +933,7 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
858
933
|
},
|
|
859
934
|
)
|
|
860
935
|
latest_tags_by_partition_result = res["data"]["eventLogs"]["getLatestTagsByPartition"]
|
|
861
|
-
latest_tags_by_partition:
|
|
936
|
+
latest_tags_by_partition: dict[str, dict[str, str]] = defaultdict(dict)
|
|
862
937
|
for tag_by_partition in latest_tags_by_partition_result:
|
|
863
938
|
latest_tags_by_partition[tag_by_partition["partition"]][tag_by_partition["key"]] = (
|
|
864
939
|
tag_by_partition["value"]
|
|
@@ -869,7 +944,7 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
869
944
|
|
|
870
945
|
def get_latest_asset_partition_materialization_attempts_without_materializations(
|
|
871
946
|
self, asset_key: AssetKey, after_storage_id: Optional[int] = None
|
|
872
|
-
) -> Mapping[str,
|
|
947
|
+
) -> Mapping[str, tuple[str, int]]:
|
|
873
948
|
res = self._execute_query(
|
|
874
949
|
GET_LATEST_ASSET_PARTITION_MATERIALIZATION_ATTEMPTS_WITHOUT_MATERIALIZATIONS,
|
|
875
950
|
variables={
|
|
@@ -882,7 +957,7 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
882
957
|
]
|
|
883
958
|
|
|
884
959
|
# Translate list to tuple
|
|
885
|
-
return {key: tuple(val) for key, val in result.items()}
|
|
960
|
+
return {key: tuple(val) for key, val in result.items()}
|
|
886
961
|
|
|
887
962
|
def get_event_tags_for_asset(
|
|
888
963
|
self,
|
|
@@ -917,6 +992,28 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
917
992
|
)
|
|
918
993
|
return res["data"]["eventLogs"]["getDynamicPartitions"]
|
|
919
994
|
|
|
995
|
+
def get_paginated_dynamic_partitions(
|
|
996
|
+
self, partitions_def_name: str, limit: int, ascending: bool, cursor: Optional[str] = None
|
|
997
|
+
) -> PaginatedResults[str]:
|
|
998
|
+
check.str_param(partitions_def_name, "partitions_def_name")
|
|
999
|
+
check.int_param(limit, "limit")
|
|
1000
|
+
check.bool_param(ascending, "ascending")
|
|
1001
|
+
check.opt_str_param(cursor, "cursor")
|
|
1002
|
+
res = self._execute_query(
|
|
1003
|
+
GET_PAGINATED_DYNAMIC_PARTITIONS_QUERY,
|
|
1004
|
+
variables={
|
|
1005
|
+
"partitionsDefName": partitions_def_name,
|
|
1006
|
+
"limit": limit,
|
|
1007
|
+
"ascending": ascending,
|
|
1008
|
+
"cursor": cursor,
|
|
1009
|
+
},
|
|
1010
|
+
)
|
|
1011
|
+
return PaginatedResults(
|
|
1012
|
+
results=res["data"]["eventLogs"]["getPaginatedDynamicPartitions"]["results"],
|
|
1013
|
+
cursor=res["data"]["eventLogs"]["getPaginatedDynamicPartitions"]["cursor"],
|
|
1014
|
+
has_more=res["data"]["eventLogs"]["getPaginatedDynamicPartitions"]["hasMore"],
|
|
1015
|
+
)
|
|
1016
|
+
|
|
920
1017
|
def has_dynamic_partition(self, partitions_def_name: str, partition_key: str) -> bool:
|
|
921
1018
|
check.str_param(partitions_def_name, "partitions_def_name")
|
|
922
1019
|
check.str_param(partition_key, "partition_key")
|
|
@@ -959,11 +1056,16 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
959
1056
|
)
|
|
960
1057
|
return res
|
|
961
1058
|
|
|
962
|
-
def wipe_asset_partitions(self, asset_key: AssetKey, partition_keys: Sequence[str])
|
|
1059
|
+
def wipe_asset_partitions(self, asset_key: AssetKey, partition_keys: Sequence[str]):
|
|
963
1060
|
"""Remove asset index history from event log for given asset partitions."""
|
|
964
|
-
|
|
965
|
-
|
|
1061
|
+
res = self._execute_query(
|
|
1062
|
+
WIPE_ASSET_PARTITIONS_MUTATION,
|
|
1063
|
+
variables={
|
|
1064
|
+
"assetKey": asset_key.to_string(),
|
|
1065
|
+
"partitionKeys": partition_keys,
|
|
1066
|
+
},
|
|
966
1067
|
)
|
|
1068
|
+
return res
|
|
967
1069
|
|
|
968
1070
|
@property
|
|
969
1071
|
def supports_global_concurrency_limits(self) -> bool:
|
|
@@ -1017,7 +1119,7 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
1017
1119
|
else:
|
|
1018
1120
|
raise DagsterCloudAgentServerError(res)
|
|
1019
1121
|
|
|
1020
|
-
def get_concurrency_keys(self) ->
|
|
1122
|
+
def get_concurrency_keys(self) -> set[str]:
|
|
1021
1123
|
res = self._execute_query(GET_CONCURRENCY_KEYS_QUERY)
|
|
1022
1124
|
return set(res["data"]["eventLogs"]["getConcurrencyKeys"])
|
|
1023
1125
|
|
|
@@ -1033,6 +1135,8 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
1033
1135
|
slot_count=info["slotCount"],
|
|
1034
1136
|
claimed_slots=[_claimed_slot_from_graphql(slot) for slot in info["claimedSlots"]],
|
|
1035
1137
|
pending_steps=[_pending_step_from_graphql(step) for step in info["pendingSteps"]],
|
|
1138
|
+
limit=info["limit"],
|
|
1139
|
+
using_default_limit=bool(info["usingDefaultLimit"]),
|
|
1036
1140
|
)
|
|
1037
1141
|
|
|
1038
1142
|
def claim_concurrency_slot(
|
|
@@ -1100,7 +1204,7 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
1100
1204
|
),
|
|
1101
1205
|
)
|
|
1102
1206
|
|
|
1103
|
-
def get_concurrency_run_ids(self) ->
|
|
1207
|
+
def get_concurrency_run_ids(self) -> set[str]:
|
|
1104
1208
|
raise NotImplementedError("Not callable from user cloud")
|
|
1105
1209
|
|
|
1106
1210
|
def free_concurrency_slots_for_run(self, run_id: str) -> None:
|
|
@@ -1127,6 +1231,7 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
1127
1231
|
check_key: AssetCheckKey,
|
|
1128
1232
|
limit: int,
|
|
1129
1233
|
cursor: Optional[int] = None,
|
|
1234
|
+
status: Optional[AbstractSet[AssetCheckExecutionRecordStatus]] = None,
|
|
1130
1235
|
) -> Sequence[AssetCheckExecutionRecord]:
|
|
1131
1236
|
raise NotImplementedError("Not callable from user cloud")
|
|
1132
1237
|
|
|
@@ -1153,6 +1258,26 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
1153
1258
|
)
|
|
1154
1259
|
return _event_records_result_from_graphql(res["data"]["eventLogs"]["fetchMaterializations"])
|
|
1155
1260
|
|
|
1261
|
+
def fetch_failed_materializations(
|
|
1262
|
+
self,
|
|
1263
|
+
records_filter: Union[AssetKey, AssetRecordsFilter],
|
|
1264
|
+
limit: int,
|
|
1265
|
+
cursor: Optional[str] = None,
|
|
1266
|
+
ascending: bool = False,
|
|
1267
|
+
) -> EventRecordsResult:
|
|
1268
|
+
res = self._execute_query(
|
|
1269
|
+
FETCH_FAILED_MATERIALIZATIONS_QUERY,
|
|
1270
|
+
variables={
|
|
1271
|
+
"recordsFilter": _get_asset_records_filter_input(records_filter),
|
|
1272
|
+
"limit": limit,
|
|
1273
|
+
"cursor": cursor,
|
|
1274
|
+
"ascending": ascending,
|
|
1275
|
+
},
|
|
1276
|
+
)
|
|
1277
|
+
return _event_records_result_from_graphql(
|
|
1278
|
+
res["data"]["eventLogs"]["fetchFailedMaterializations"]
|
|
1279
|
+
)
|
|
1280
|
+
|
|
1156
1281
|
def fetch_observations(
|
|
1157
1282
|
self,
|
|
1158
1283
|
records_filter: Union[AssetKey, AssetRecordsFilter],
|
|
@@ -1191,6 +1316,10 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
1191
1316
|
res["data"]["eventLogs"]["fetchPlannedMaterializations"]
|
|
1192
1317
|
)
|
|
1193
1318
|
|
|
1319
|
+
@property
|
|
1320
|
+
def supports_run_status_change_job_name_filter(self):
|
|
1321
|
+
return True
|
|
1322
|
+
|
|
1194
1323
|
def fetch_run_status_changes(
|
|
1195
1324
|
self,
|
|
1196
1325
|
records_filter: Union[DagsterEventType, RunStatusChangeRecordsFilter],
|
|
@@ -1233,7 +1362,7 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
1233
1362
|
|
|
1234
1363
|
def get_updated_data_version_partitions(
|
|
1235
1364
|
self, asset_key: AssetKey, partitions: Iterable[str], since_storage_id: int
|
|
1236
|
-
) ->
|
|
1365
|
+
) -> set[str]:
|
|
1237
1366
|
res = self._execute_query(
|
|
1238
1367
|
GET_UPDATED_DATA_VERSION_PARTITIONS,
|
|
1239
1368
|
variables={
|
|
@@ -1244,3 +1373,67 @@ class GraphQLEventLogStorage(EventLogStorage, ConfigurableClass):
|
|
|
1244
1373
|
)
|
|
1245
1374
|
partitions = res["data"]["eventLogs"]["getUpdatedDataVersionPartitions"]
|
|
1246
1375
|
return set(partitions)
|
|
1376
|
+
|
|
1377
|
+
@property
|
|
1378
|
+
def handles_run_events_in_store_event(self) -> bool:
|
|
1379
|
+
return True
|
|
1380
|
+
|
|
1381
|
+
def default_run_scoped_event_tailer_offset(self) -> int:
|
|
1382
|
+
return DEFAULT_RUN_SCOPED_EVENT_TAILER_OFFSET
|
|
1383
|
+
|
|
1384
|
+
def get_asset_status_cache_values(
|
|
1385
|
+
self,
|
|
1386
|
+
partitions_defs_by_key: Iterable[tuple[AssetKey, Optional[PartitionsDefinition]]],
|
|
1387
|
+
context,
|
|
1388
|
+
) -> Sequence[Optional[AssetStatusCacheValue]]:
|
|
1389
|
+
asset_keys = [key for key, _ in partitions_defs_by_key]
|
|
1390
|
+
res = self._execute_query(
|
|
1391
|
+
GET_ASSET_STATUS_CACHE_VALUES,
|
|
1392
|
+
variables={
|
|
1393
|
+
"assetKeys": [asset_key.to_graphql_input() for asset_key in asset_keys],
|
|
1394
|
+
},
|
|
1395
|
+
)
|
|
1396
|
+
|
|
1397
|
+
return [
|
|
1398
|
+
AssetStatusCacheValue(
|
|
1399
|
+
latest_storage_id=value["latestStorageId"],
|
|
1400
|
+
partitions_def_id=value["partitionsDefId"],
|
|
1401
|
+
serialized_materialized_partition_subset=value[
|
|
1402
|
+
"serializedMaterializedPartitionSubset"
|
|
1403
|
+
],
|
|
1404
|
+
serialized_failed_partition_subset=value["serializedFailedPartitionSubset"],
|
|
1405
|
+
serialized_in_progress_partition_subset=value[
|
|
1406
|
+
"serializedInProgressPartitionSubset"
|
|
1407
|
+
],
|
|
1408
|
+
earliest_in_progress_materialization_event_id=value[
|
|
1409
|
+
"earliestInProgressMaterializationEventId"
|
|
1410
|
+
],
|
|
1411
|
+
)
|
|
1412
|
+
if value
|
|
1413
|
+
else None
|
|
1414
|
+
for value in res["data"]["eventLogs"]["getAssetStatusCacheValues"]
|
|
1415
|
+
]
|
|
1416
|
+
|
|
1417
|
+
def get_pool_config(self):
|
|
1418
|
+
res = self._execute_query(GET_POOL_CONFIG_QUERY)
|
|
1419
|
+
pool_config = res["data"]["eventLogs"]["getPoolConfig"]
|
|
1420
|
+
granularity_str = pool_config.get("poolGranularity")
|
|
1421
|
+
|
|
1422
|
+
return PoolConfig(
|
|
1423
|
+
pool_granularity=PoolGranularity(granularity_str) if granularity_str else None,
|
|
1424
|
+
default_pool_limit=pool_config.get("defaultPoolLimit"),
|
|
1425
|
+
op_granularity_run_buffer=pool_config.get("opGranularityRunBuffer"),
|
|
1426
|
+
)
|
|
1427
|
+
|
|
1428
|
+
def get_pool_limits(self) -> Sequence[PoolLimit]:
|
|
1429
|
+
"""Get the set of concurrency limited keys and limits."""
|
|
1430
|
+
res = self._execute_query(GET_POOL_LIMITS_QUERY)
|
|
1431
|
+
limits = res["data"]["eventLogs"]["getPoolLimits"]
|
|
1432
|
+
return [
|
|
1433
|
+
PoolLimit(
|
|
1434
|
+
name=limit.get("name"),
|
|
1435
|
+
limit=limit.get("limit"),
|
|
1436
|
+
from_default=limit.get("fromDefault"),
|
|
1437
|
+
)
|
|
1438
|
+
for limit in limits
|
|
1439
|
+
]
|