vellum-workflow-server 1.4.0__tar.gz → 1.4.0.post1__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 vellum-workflow-server might be problematic. Click here for more details.

Files changed (33) hide show
  1. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/PKG-INFO +1 -1
  2. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/pyproject.toml +1 -1
  3. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/api/workflow_view.py +11 -4
  4. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/utils/oom_killer.py +4 -1
  5. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/utils/system_utils.py +34 -0
  6. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/README.md +0 -0
  7. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/__init__.py +0 -0
  8. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/api/__init__.py +0 -0
  9. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/api/auth_middleware.py +0 -0
  10. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/api/healthz_view.py +0 -0
  11. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/api/tests/__init__.py +0 -0
  12. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/api/tests/test_input_display_mapping.py +0 -0
  13. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/api/tests/test_workflow_view.py +0 -0
  14. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/api/tests/test_workflow_view_stream_workflow_route.py +0 -0
  15. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/code_exec_runner.py +0 -0
  16. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/config.py +0 -0
  17. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/core/__init__.py +0 -0
  18. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/core/cancel_workflow.py +0 -0
  19. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/core/events.py +0 -0
  20. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/core/executor.py +0 -0
  21. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/core/utils.py +0 -0
  22. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/core/workflow_executor_context.py +0 -0
  23. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/server.py +0 -0
  24. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/start.py +0 -0
  25. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/utils/__init__.py +0 -0
  26. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/utils/exit_handler.py +0 -0
  27. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/utils/log_proxy.py +0 -0
  28. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/utils/sentry.py +0 -0
  29. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/utils/tests/__init__.py +0 -0
  30. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/utils/tests/test_sentry_integration.py +0 -0
  31. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/utils/tests/test_system_utils.py +0 -0
  32. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/utils/tests/test_utils.py +0 -0
  33. {vellum_workflow_server-1.4.0 → vellum_workflow_server-1.4.0.post1}/src/workflow_server/utils/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-workflow-server
3
- Version: 1.4.0
3
+ Version: 1.4.0.post1
4
4
  Summary:
5
5
  License: AGPL
6
6
  Requires-Python: >=3.9.0,<4
@@ -3,7 +3,7 @@ name = "vellum-workflow-server"
3
3
 
4
4
  [tool.poetry]
5
5
  name = "vellum-workflow-server"
6
- version = "1.4.0"
6
+ version = "1.4.0.post1"
7
7
  description = ""
8
8
  readme = "README.md"
9
9
  authors = []
@@ -49,8 +49,10 @@ from workflow_server.core.workflow_executor_context import (
49
49
  )
50
50
  from workflow_server.utils.oom_killer import get_is_oom_killed
51
51
  from workflow_server.utils.system_utils import (
52
+ add_active_span_id,
52
53
  get_active_process_count,
53
54
  increment_process_count,
55
+ remove_active_span_id,
54
56
  wait_for_available_process,
55
57
  )
56
58
  from workflow_server.utils.utils import convert_json_inputs_to_vellum, get_version
@@ -182,10 +184,7 @@ def stream_workflow_route() -> Response:
182
184
  first_item = next(stream_iterator)
183
185
  increment_process_count(1)
184
186
 
185
- if isinstance(first_item, str) and first_item.startswith(SPAN_ID_EVENT):
186
- span_id = first_item.split(":")[1]
187
- headers["X-Vellum-Workflow-Span-Id"] = span_id
188
- else:
187
+ if not isinstance(first_item, str) or not first_item.startswith(SPAN_ID_EVENT):
189
188
  logger.error("Workflow stream did not start with span id event")
190
189
  return Response(
191
190
  json.dumps({"detail": "Internal Server Error"}),
@@ -194,6 +193,10 @@ def stream_workflow_route() -> Response:
194
193
  headers=headers,
195
194
  )
196
195
 
196
+ span_id = first_item.split(":")[1]
197
+ headers["X-Vellum-Workflow-Span-Id"] = span_id
198
+ add_active_span_id(span_id)
199
+
197
200
  logger.info(f"Starting Workflow Stream, execution ID: {span_id}, ")
198
201
 
199
202
  def process_events(queue: Queue) -> Iterator[Union[str, dict]]:
@@ -227,6 +230,7 @@ def stream_workflow_route() -> Response:
227
230
 
228
231
  if not ENABLE_PROCESS_WRAPPER or process:
229
232
  increment_process_count(-1)
233
+ remove_active_span_id(span_id)
230
234
 
231
235
  yield VembdaExecutionFulfilledEvent(
232
236
  id=uuid4(),
@@ -254,6 +258,7 @@ def stream_workflow_route() -> Response:
254
258
  process.kill()
255
259
  if process:
256
260
  increment_process_count(-1)
261
+ remove_active_span_id(span_id)
257
262
 
258
263
  break
259
264
 
@@ -332,10 +337,12 @@ def stream_workflow_route() -> Response:
332
337
  process.kill()
333
338
  if process:
334
339
  increment_process_count(-1)
340
+ remove_active_span_id(span_id)
335
341
  except Exception as e:
336
342
  logger.error("Failed to kill process", e)
337
343
  else:
338
344
  increment_process_count(-1)
345
+ remove_active_span_id(span_id)
339
346
 
340
347
  resp = Response(
341
348
  stream_with_context(generator()),
@@ -15,6 +15,7 @@ from workflow_server.utils.system_utils import (
15
15
  FORCE_GC_MEMORY_PERCENT,
16
16
  WARN_MEMORY_PERCENT,
17
17
  get_active_process_count,
18
+ get_active_span_ids,
18
19
  get_memory_in_use_mb,
19
20
  )
20
21
 
@@ -71,8 +72,10 @@ class OomKillerThread(Thread):
71
72
 
72
73
  if memory_mb > (MEMORY_LIMIT_MB * _MAX_MEMORY_PERCENT):
73
74
  self._kill_switch.set()
75
+ active_span_ids = get_active_span_ids()
74
76
  logger.error(
75
- f"Workflow server OOM killed, memory: {memory_mb}MB, Process Count: {get_active_process_count()}"
77
+ f"Workflow server OOM killed, memory: {memory_mb}MB, Process Count: {get_active_process_count()}",
78
+ extra={"active_span_ids": active_span_ids},
76
79
  )
77
80
  # Give time for the threads to get our kill switch
78
81
  sleep(_KILL_GRACE_PERIOD)
@@ -17,6 +17,7 @@ _MEMORY_CHECK_INTERVAL_SECONDS = 2
17
17
  _MAX_MEMORY_CHECK_ATTEMPTS = 3
18
18
  _ACTIVE_PROCESS_COUNT = multiprocessing.Value("i", 0)
19
19
  _ACTIVE_PROCESS_LOCK = multiprocessing.Lock()
20
+ _ACTIVE_SPAN_IDS = multiprocessing.Manager().list()
20
21
 
21
22
 
22
23
  def increment_process_count(change: int) -> None:
@@ -36,6 +37,39 @@ def get_active_process_count() -> int:
36
37
  return _ACTIVE_PROCESS_COUNT.value # type: ignore
37
38
 
38
39
 
40
+ def get_active_span_ids() -> list[str]:
41
+ """Get a copy of currently active span IDs"""
42
+ with _ACTIVE_PROCESS_LOCK:
43
+ return list(_ACTIVE_SPAN_IDS)
44
+
45
+
46
+ def add_active_span_id(span_id: str) -> None:
47
+ """Add a span ID to the active tracking list"""
48
+ result = _ACTIVE_PROCESS_LOCK.acquire(timeout=5)
49
+ try:
50
+ if result:
51
+ _ACTIVE_SPAN_IDS.append(span_id)
52
+ else:
53
+ logger.error("Failed to lock workflow server span ID tracking.")
54
+ finally:
55
+ if result:
56
+ _ACTIVE_PROCESS_LOCK.release()
57
+
58
+
59
+ def remove_active_span_id(span_id: str) -> None:
60
+ """Remove a span ID from the active tracking list"""
61
+ result = _ACTIVE_PROCESS_LOCK.acquire(timeout=5)
62
+ try:
63
+ if result and span_id in _ACTIVE_SPAN_IDS:
64
+ _ACTIVE_SPAN_IDS.remove(span_id)
65
+ else:
66
+ if not result:
67
+ logger.error("Failed to lock workflow server span ID tracking.")
68
+ finally:
69
+ if result:
70
+ _ACTIVE_PROCESS_LOCK.release()
71
+
72
+
39
73
  def get_memory_in_use_mb() -> Optional[float]:
40
74
  try:
41
75
  with open("/sys/fs/cgroup/memory/memory.usage_in_bytes", "r") as file: