dagster-k8s 0.26.9__tar.gz → 0.26.10__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 dagster-k8s might be problematic. Click here for more details.

Files changed (28) hide show
  1. {dagster-k8s-0.26.9/dagster_k8s.egg-info → dagster-k8s-0.26.10}/PKG-INFO +1 -1
  2. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/dagster_k8s/pipes.py +90 -9
  3. dagster-k8s-0.26.10/dagster_k8s/version.py +1 -0
  4. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10/dagster_k8s.egg-info}/PKG-INFO +1 -1
  5. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/dagster_k8s.egg-info/requires.txt +1 -1
  6. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/setup.py +1 -1
  7. dagster-k8s-0.26.9/dagster_k8s/version.py +0 -1
  8. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/LICENSE +0 -0
  9. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/MANIFEST.in +0 -0
  10. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/README.md +0 -0
  11. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/dagster_k8s/__init__.py +0 -0
  12. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/dagster_k8s/client.py +0 -0
  13. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/dagster_k8s/container_context.py +0 -0
  14. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/dagster_k8s/executor.py +0 -0
  15. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/dagster_k8s/job.py +0 -0
  16. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/dagster_k8s/kubernetes_version.py +0 -0
  17. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/dagster_k8s/launcher.py +0 -0
  18. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/dagster_k8s/models.py +0 -0
  19. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/dagster_k8s/ops/__init__.py +0 -0
  20. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/dagster_k8s/ops/k8s_job_op.py +0 -0
  21. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/dagster_k8s/py.typed +0 -0
  22. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/dagster_k8s/test.py +0 -0
  23. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/dagster_k8s/utils.py +0 -0
  24. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/dagster_k8s.egg-info/SOURCES.txt +0 -0
  25. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/dagster_k8s.egg-info/dependency_links.txt +0 -0
  26. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/dagster_k8s.egg-info/not-zip-safe +0 -0
  27. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/dagster_k8s.egg-info/top_level.txt +0 -0
  28. {dagster-k8s-0.26.9 → dagster-k8s-0.26.10}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dagster-k8s
3
- Version: 0.26.9
3
+ Version: 0.26.10
4
4
  Summary: A Dagster integration for k8s
5
5
  Home-page: https://github.com/dagster-io/dagster/tree/master/python_modules/libraries/dagster-k8s
6
6
  Author: Dagster Labs
@@ -34,6 +34,7 @@ from dagster._core.pipes.utils import (
34
34
  extract_message_or_forward_to_stdout,
35
35
  open_pipes_session,
36
36
  )
37
+ from dagster._time import parse_time_string
37
38
  from dagster_pipes import (
38
39
  DAGSTER_PIPES_CONTEXT_ENV_VAR,
39
40
  DAGSTER_PIPES_MESSAGES_ENV_VAR,
@@ -41,6 +42,7 @@ from dagster_pipes import (
41
42
  PipesExtras,
42
43
  encode_env_var,
43
44
  )
45
+ from urllib3.exceptions import ReadTimeoutError
44
46
 
45
47
  from dagster_k8s.client import (
46
48
  DEFAULT_WAIT_BETWEEN_ATTEMPTS,
@@ -65,6 +67,11 @@ DEFAULT_CONTAINER_NAME = "dagster-pipes-execution"
65
67
  _NAMESPACE_SECRET_PATH = Path("/var/run/secrets/kubernetes.io/serviceaccount/namespace")
66
68
  _DEV_NULL_MESSAGE_WRITER = encode_env_var({"path": "/dev/null"})
67
69
 
70
+ DEFAULT_CONSUME_POD_LOGS_RETRIES = 5
71
+
72
+ # By default, timeout and reconnect to the log stream every hour.
73
+ DEFAULT_DAGSTER_PIPES_K8S_CONSUME_POD_LOGS_REQUEST_TIMEOUT = 3600
74
+
68
75
 
69
76
  class PipesK8sPodLogsMessageReader(PipesMessageReader):
70
77
  """Message reader that reads messages from kubernetes pod logs."""
@@ -80,24 +87,97 @@ class PipesK8sPodLogsMessageReader(PipesMessageReader):
80
87
  finally:
81
88
  self._handler = None
82
89
 
90
+ def _get_consume_logs_request_timeout(self) -> Optional[int]:
91
+ request_timeout_env_var = os.getenv("DAGSTER_PIPES_K8S_CONSUME_POD_LOGS_REQUEST_TIMEOUT")
92
+ if request_timeout_env_var:
93
+ return int(request_timeout_env_var)
94
+
95
+ return DEFAULT_DAGSTER_PIPES_K8S_CONSUME_POD_LOGS_REQUEST_TIMEOUT
96
+
83
97
  def consume_pod_logs(
84
98
  self,
99
+ context: Union[OpExecutionContext, AssetExecutionContext],
85
100
  core_api: kubernetes.client.CoreV1Api,
86
101
  pod_name: str,
87
102
  namespace: str,
88
103
  ):
104
+ last_seen_timestamp = None
105
+ catching_up_after_retry = False
106
+
107
+ request_timeout = self._get_consume_logs_request_timeout()
108
+
109
+ retries_remaining = int(
110
+ os.getenv(
111
+ "DAGSTER_PIPES_K8S_CONSUME_POD_LOGS_RETRIES", str(DEFAULT_CONSUME_POD_LOGS_RETRIES)
112
+ )
113
+ )
114
+
89
115
  handler = check.not_none(
90
116
  self._handler, "can only consume logs within scope of context manager"
91
117
  )
92
- for line in core_api.read_namespaced_pod_log(
93
- pod_name,
94
- namespace,
95
- follow=True,
96
- _preload_content=False, # avoid JSON processing
97
- ).stream():
98
- log_chunk = line.decode("utf-8")
99
- for log_line in log_chunk.split("\n"):
100
- extract_message_or_forward_to_stdout(handler, log_line)
118
+
119
+ while True:
120
+ # On retry, re-connect to the log stream for new messages since the last seen timestamp
121
+ # (with a buffer to ensure none are missed). The messages are deduplicated by timestamp below.
122
+ if last_seen_timestamp:
123
+ since_seconds = int(
124
+ max(time.time() - parse_time_string(last_seen_timestamp).timestamp(), 0)
125
+ + int(os.getenv("DAGSTER_PIPES_K8S_CONSUME_POD_LOGS_BUFFER_SECONDS", "300"))
126
+ )
127
+ else:
128
+ since_seconds = None
129
+
130
+ try:
131
+ for log_item in _process_log_stream(
132
+ core_api.read_namespaced_pod_log(
133
+ pod_name,
134
+ namespace,
135
+ follow=True,
136
+ timestamps=True,
137
+ since_seconds=since_seconds,
138
+ _preload_content=False, # avoid JSON processing
139
+ _request_timeout=request_timeout,
140
+ )
141
+ ):
142
+ timestamp = log_item.timestamp
143
+ message = log_item.log
144
+
145
+ if (
146
+ catching_up_after_retry
147
+ and timestamp
148
+ and last_seen_timestamp
149
+ and timestamp <= last_seen_timestamp
150
+ ):
151
+ # This is a log that we've already seen before from before we retried
152
+ continue
153
+ else:
154
+ catching_up_after_retry = False
155
+ extract_message_or_forward_to_stdout(handler, message)
156
+ if timestamp:
157
+ last_seen_timestamp = (
158
+ max(last_seen_timestamp, timestamp)
159
+ if last_seen_timestamp
160
+ else timestamp
161
+ )
162
+ return
163
+ except Exception as e:
164
+ # Expected read timeouts can occur for long-running pods if a request timeout is set
165
+ expected_read_timeout = isinstance(e, ReadTimeoutError) and request_timeout
166
+
167
+ if expected_read_timeout:
168
+ # Expected so doesn't need to be logged to event log, but write to stdout
169
+ # for visibility
170
+ logging.getLogger("dagster").info("Re-connecting to pod logs stream")
171
+ else:
172
+ if retries_remaining == 0:
173
+ raise
174
+ retries_remaining -= 1
175
+ context.log.warning(
176
+ f"Error consuming pod logs. {retries_remaining} retr{('y' if retries_remaining==1 else 'ies')} remaining",
177
+ exc_info=True,
178
+ )
179
+
180
+ catching_up_after_retry = True
101
181
 
102
182
  @contextmanager
103
183
  def async_consume_pod_logs(
@@ -504,6 +584,7 @@ class PipesK8sClient(PipesClient, TreatAsResourceParam):
504
584
  return
505
585
  else:
506
586
  self.message_reader.consume_pod_logs(
587
+ context=context,
507
588
  core_api=client.core_api,
508
589
  namespace=namespace,
509
590
  pod_name=pod_name,
@@ -0,0 +1 @@
1
+ __version__ = "0.26.10"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dagster-k8s
3
- Version: 0.26.9
3
+ Version: 0.26.10
4
4
  Summary: A Dagster integration for k8s
5
5
  Home-page: https://github.com/dagster-io/dagster/tree/master/python_modules/libraries/dagster-k8s
6
6
  Author: Dagster Labs
@@ -1,3 +1,3 @@
1
- dagster==1.10.9
1
+ dagster==1.10.10
2
2
  kubernetes<33
3
3
  google-auth!=2.23.1
@@ -42,7 +42,7 @@ setup(
42
42
  include_package_data=True,
43
43
  python_requires=">=3.9,<3.13",
44
44
  install_requires=[
45
- "dagster==1.10.9",
45
+ "dagster==1.10.10",
46
46
  f"kubernetes<{KUBERNETES_VERSION_UPPER_BOUND}",
47
47
  # exclude a google-auth release that added an overly restrictive urllib3 pin that confuses dependency resolvers
48
48
  "google-auth!=2.23.1",
@@ -1 +0,0 @@
1
- __version__ = "0.26.9"
File without changes
File without changes
File without changes
File without changes