dv-flow-mgr 1.7.14886019138rc0__py3-none-any.whl → 1.8.14920283751rc0__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.
- dv_flow/mgr/__init__.py +2 -2
- dv_flow/mgr/cmds/cmd_run.py +11 -0
- dv_flow/mgr/task_listener_trace.py +160 -0
- dv_flow/mgr/task_node.py +3 -2
- {dv_flow_mgr-1.7.14886019138rc0.dist-info → dv_flow_mgr-1.8.14920283751rc0.dist-info}/METADATA +1 -1
- {dv_flow_mgr-1.7.14886019138rc0.dist-info → dv_flow_mgr-1.8.14920283751rc0.dist-info}/RECORD +10 -9
- {dv_flow_mgr-1.7.14886019138rc0.dist-info → dv_flow_mgr-1.8.14920283751rc0.dist-info}/WHEEL +0 -0
- {dv_flow_mgr-1.7.14886019138rc0.dist-info → dv_flow_mgr-1.8.14920283751rc0.dist-info}/entry_points.txt +0 -0
- {dv_flow_mgr-1.7.14886019138rc0.dist-info → dv_flow_mgr-1.8.14920283751rc0.dist-info}/licenses/LICENSE +0 -0
- {dv_flow_mgr-1.7.14886019138rc0.dist-info → dv_flow_mgr-1.8.14920283751rc0.dist-info}/top_level.txt +0 -0
dv_flow/mgr/__init__.py
CHANGED
@@ -31,7 +31,7 @@ from .task_node_ctor_wrapper import task
|
|
31
31
|
from .task_runner import TaskSetRunner
|
32
32
|
from .task_listener_log import TaskListenerLog
|
33
33
|
|
34
|
-
VERSION="1.
|
35
|
-
SUFFIX="
|
34
|
+
VERSION="1.8.0"
|
35
|
+
SUFFIX="14920283751rc0"
|
36
36
|
__version__="%s%s" % (VERSION, SUFFIX)
|
37
37
|
|
dv_flow/mgr/cmds/cmd_run.py
CHANGED
@@ -28,6 +28,7 @@ from ..task_data import SeverityE
|
|
28
28
|
from ..task_graph_builder import TaskGraphBuilder
|
29
29
|
from ..task_runner import TaskSetRunner
|
30
30
|
from ..task_listener_log import TaskListenerLog
|
31
|
+
from ..task_listener_trace import TaskListenerTrace
|
31
32
|
|
32
33
|
|
33
34
|
class CmdRun(object):
|
@@ -98,7 +99,14 @@ class CmdRun(object):
|
|
98
99
|
if args.j != -1:
|
99
100
|
runner.nproc = int(args.j)
|
100
101
|
|
102
|
+
if not os.path.isdir(os.path.join(rundir, "log")):
|
103
|
+
os.makedirs(os.path.join(rundir, "log"))
|
104
|
+
|
105
|
+
fp = open(os.path.join(rundir, "log", "%s.trace.json" % pkg.name), "w")
|
106
|
+
trace = TaskListenerTrace(fp)
|
107
|
+
|
101
108
|
runner.add_listener(listener.event)
|
109
|
+
runner.add_listener(trace.event)
|
102
110
|
|
103
111
|
tasks = []
|
104
112
|
|
@@ -110,6 +118,9 @@ class CmdRun(object):
|
|
110
118
|
|
111
119
|
asyncio.run(runner.run(tasks))
|
112
120
|
|
121
|
+
trace.close()
|
122
|
+
fp.close()
|
123
|
+
|
113
124
|
return runner.status
|
114
125
|
|
115
126
|
|
@@ -0,0 +1,160 @@
|
|
1
|
+
import dataclasses as dc
|
2
|
+
import json
|
3
|
+
import time
|
4
|
+
from typing import Dict, List, TextIO
|
5
|
+
from .task_node import TaskNode
|
6
|
+
|
7
|
+
@dc.dataclass
|
8
|
+
class TaskListenerTrace(object):
|
9
|
+
"""Task listener that generates Google Trace Event Format output."""
|
10
|
+
|
11
|
+
fp: TextIO # File to write trace events to
|
12
|
+
_free_tids: List = dc.field(default_factory=list) # Pool of available thread IDs
|
13
|
+
_task_tid_map: Dict = dc.field(default_factory=dict) # Map of tasks to their assigned thread IDs
|
14
|
+
_next_tid: int = dc.field(default=1) # Next thread ID to assign if pool is empty
|
15
|
+
_next_flow_id: int = dc.field(default=1) # Counter for unique flow IDs
|
16
|
+
_events: List = dc.field(default_factory=list) # Store events in memory
|
17
|
+
|
18
|
+
def __post_init__(self):
|
19
|
+
# Add metadata event
|
20
|
+
self._events.append({
|
21
|
+
"name": "metadata",
|
22
|
+
"ph": "M",
|
23
|
+
"pid": 1,
|
24
|
+
"tid": 0,
|
25
|
+
"args": {
|
26
|
+
"name": "Task Execution",
|
27
|
+
"timeUnit": "us"
|
28
|
+
}
|
29
|
+
})
|
30
|
+
|
31
|
+
def close(self):
|
32
|
+
"""Write the complete trace file and close it."""
|
33
|
+
trace = {
|
34
|
+
"traceEvents": self._events,
|
35
|
+
"displayTimeUnit": "ms" # Show times in milliseconds in the viewer
|
36
|
+
}
|
37
|
+
json.dump(trace, self.fp, indent=2)
|
38
|
+
self.fp.flush()
|
39
|
+
|
40
|
+
def _get_tid(self, task: TaskNode) -> int:
|
41
|
+
"""Get a thread ID for a task, either from the pool or creating a new one."""
|
42
|
+
if task in self._task_tid_map:
|
43
|
+
return self._task_tid_map[task]
|
44
|
+
|
45
|
+
if len(self._free_tids) > 0:
|
46
|
+
tid = self._free_tids.pop()
|
47
|
+
else:
|
48
|
+
tid = self._next_tid
|
49
|
+
self._next_tid += 1
|
50
|
+
|
51
|
+
self._task_tid_map[task] = tid
|
52
|
+
return tid
|
53
|
+
|
54
|
+
def _release_tid(self, task: TaskNode):
|
55
|
+
"""Return a task's thread ID to the pool."""
|
56
|
+
if task in self._task_tid_map:
|
57
|
+
tid = self._task_tid_map[task]
|
58
|
+
del self._task_tid_map[task]
|
59
|
+
self._free_tids.append(tid)
|
60
|
+
|
61
|
+
def event(self, task: TaskNode, reason: str):
|
62
|
+
"""Record a task execution event.
|
63
|
+
|
64
|
+
Args:
|
65
|
+
task: The task that generated the event
|
66
|
+
reason: Either 'enter' or 'leave' marking start/end of task execution
|
67
|
+
"""
|
68
|
+
# Get/create thread ID for this task
|
69
|
+
tid = self._get_tid(task)
|
70
|
+
|
71
|
+
# Map the event type
|
72
|
+
ph = 'B' if reason == 'enter' else 'E'
|
73
|
+
|
74
|
+
# Get current timestamp in microseconds
|
75
|
+
ts = int(time.time() * 1_000_000) if reason == "enter" else int(task.end.timestamp() * 1_000_000)
|
76
|
+
|
77
|
+
# Create the duration event
|
78
|
+
event = {
|
79
|
+
"name": task.name,
|
80
|
+
"cat": "task",
|
81
|
+
"ph": ph,
|
82
|
+
"pid": 1,
|
83
|
+
"tid": tid,
|
84
|
+
"ts": ts
|
85
|
+
}
|
86
|
+
|
87
|
+
# Store the duration event
|
88
|
+
self._events.append(event)
|
89
|
+
|
90
|
+
if reason == "enter":
|
91
|
+
# When a task starts, create flow events from all its dependencies
|
92
|
+
for need, _ in task.needs:
|
93
|
+
flow_id = self._next_flow_id
|
94
|
+
self._next_flow_id += 1
|
95
|
+
|
96
|
+
# # Add flow end event connecting to this task
|
97
|
+
# flow_end = {
|
98
|
+
# "name": f"{need.name} -> {task.name}",
|
99
|
+
# "cat": "flow",
|
100
|
+
# "ph": "e", # Flow end
|
101
|
+
# "pid": 1,
|
102
|
+
# "tid": tid, # Target task's thread
|
103
|
+
# "ts": ts,
|
104
|
+
# "id": flow_id,
|
105
|
+
# "bp": "e" # Connect to enclosing slice
|
106
|
+
# }
|
107
|
+
# self._events.append(flow_end)
|
108
|
+
|
109
|
+
# # Add flow start event from dependency
|
110
|
+
# flow_start = {
|
111
|
+
# "name": f"{need.name} -> {task.name}",
|
112
|
+
# "cat": "flow",
|
113
|
+
# "ph": "b", # Flow begin
|
114
|
+
# "pid": 1,
|
115
|
+
# "tid": self._task_tid_map.get(need, 0), # Source task's thread
|
116
|
+
# "ts": int(need.end.timestamp() * 1_000_000) if need.end else ts,
|
117
|
+
# "id": flow_id,
|
118
|
+
# "bp": "e" # Connect to enclosing slice
|
119
|
+
# }
|
120
|
+
# self._events.append(flow_start)
|
121
|
+
|
122
|
+
elif reason == 'leave':
|
123
|
+
# For completed tasks, emit flow start events
|
124
|
+
if task.result:
|
125
|
+
event["args"] = {
|
126
|
+
"status": task.result.status,
|
127
|
+
"changed": task.result.changed
|
128
|
+
}
|
129
|
+
|
130
|
+
# Find any tasks that depend on this one and create flow events
|
131
|
+
for dep_task, dep_tid in self._task_tid_map.items():
|
132
|
+
if any(need[0] is task for need in dep_task.needs):
|
133
|
+
# # Create flow start event
|
134
|
+
# flow = {
|
135
|
+
# "name": f"{task.name} -> {dep_task.name}",
|
136
|
+
# "cat": "flow",
|
137
|
+
# "ph": "s", # Flow start
|
138
|
+
# "pid": 1,
|
139
|
+
# "tid": tid, # Source task's thread
|
140
|
+
# "ts": ts, # Use task end time
|
141
|
+
# "id": self._next_flow_id,
|
142
|
+
# "bp": "e" # Connect to enclosing slice
|
143
|
+
# }
|
144
|
+
# self._events.append(flow)
|
145
|
+
|
146
|
+
# # Create flow end event
|
147
|
+
# flow_end = {
|
148
|
+
# "name": f"{task.name} -> {dep_task.name}",
|
149
|
+
# "cat": "flow",
|
150
|
+
# "ph": "f", # Flow finish
|
151
|
+
# "pid": 1,
|
152
|
+
# "tid": dep_tid, # Target task's thread
|
153
|
+
# "ts": ts, # Will be updated when target task starts
|
154
|
+
# "id": self._next_flow_id,
|
155
|
+
# "bp": "e" # Connect to enclosing slice
|
156
|
+
# }
|
157
|
+
# self._events.append(flow_end)
|
158
|
+
self._next_flow_id += 1
|
159
|
+
|
160
|
+
self._release_tid(task)
|
dv_flow/mgr/task_node.py
CHANGED
@@ -24,6 +24,7 @@ import json
|
|
24
24
|
import os
|
25
25
|
import sys
|
26
26
|
import dataclasses as dc
|
27
|
+
import datetime
|
27
28
|
import pydantic.dataclasses as pdc
|
28
29
|
import logging
|
29
30
|
import toposort
|
@@ -55,8 +56,8 @@ class TaskNode(object):
|
|
55
56
|
rundir : List[str] = dc.field(default=None)
|
56
57
|
output : TaskDataOutput = dc.field(default=None)
|
57
58
|
result : TaskDataResult = dc.field(default=None)
|
58
|
-
start :
|
59
|
-
end :
|
59
|
+
start : datetime.datetime = dc.field(default=None)
|
60
|
+
end : datetime.datetime = dc.field(default=None)
|
60
61
|
save_exec_data : bool = dc.field(default=True)
|
61
62
|
iff : bool = dc.field(default=True)
|
62
63
|
parent : 'TaskNode' = dc.field(default=None)
|
{dv_flow_mgr-1.7.14886019138rc0.dist-info → dv_flow_mgr-1.8.14920283751rc0.dist-info}/RECORD
RENAMED
@@ -1,4 +1,4 @@
|
|
1
|
-
dv_flow/mgr/__init__.py,sha256=
|
1
|
+
dv_flow/mgr/__init__.py,sha256=NUUQLnpk4-yjT3DaUH9ugThEF8n1nqhlzLs6YW9zLHU,1315
|
2
2
|
dv_flow/mgr/__main__.py,sha256=BogNdBkXhgg05E8_IumNkVoag6WwvfbpiI8346oOtPo,3844
|
3
3
|
dv_flow/mgr/cond_def.py,sha256=2ZkzPusqVkN1fFMTvkDl9O_OJLPdD_cK3xzX9J75RMw,343
|
4
4
|
dv_flow/mgr/config.py,sha256=b2MVlVVNB0psk8x4bQRAYshkpNJrtyMtV1Ymhmx9AfM,137
|
@@ -37,7 +37,8 @@ dv_flow/mgr/task_def.py,sha256=8NPwtTROfWDkMqcO9mKXV4dw0sC4mCMmnsNuv8uTdTY,5094
|
|
37
37
|
dv_flow/mgr/task_graph_builder.py,sha256=q7BS7OLYkS6uZwQLvo6P_CtJkhIvPal_tXLZHgUuLpU,28172
|
38
38
|
dv_flow/mgr/task_graph_dot_writer.py,sha256=qK4Imy9o2_F1aKoU1tJ-qoBHslq2BhSMbdjAUPfpN7I,6009
|
39
39
|
dv_flow/mgr/task_listener_log.py,sha256=Ai-6X5BOoGsaNTgnlXEW0-czrjJm7__ShNK501CUmko,4337
|
40
|
-
dv_flow/mgr/
|
40
|
+
dv_flow/mgr/task_listener_trace.py,sha256=76Fqb7hiAT2GH8_-_bMRAl6T2lrTly6sP1Zis6BG3wU,6192
|
41
|
+
dv_flow/mgr/task_node.py,sha256=OC3rkeRSFv9wmgkMZ_7eJu7nuXGJcwW_b6FGQM-w7AU,5231
|
41
42
|
dv_flow/mgr/task_node_compound.py,sha256=0biBPT_2SpCPJL7DFaFY27_K7kNxJ1taIut3Fv12HXk,3347
|
42
43
|
dv_flow/mgr/task_node_ctor.py,sha256=YsoVMX5WbpbzcHvEK7ps_ZRV-J7MZ3F8NNozQw7vbog,4418
|
43
44
|
dv_flow/mgr/task_node_ctor_compound.py,sha256=290JdcTnL3b3Gv7s_wRLjdM02ezKhc9QnxZE0mv72i8,4379
|
@@ -56,7 +57,7 @@ dv_flow/mgr/type.py,sha256=hoJTatlPC0yOazKSWduK-5CfY38RPkc6qXFzOCcVSdM,723
|
|
56
57
|
dv_flow/mgr/type_def.py,sha256=4sge3PibO1jDnS0cXdX0PiurcKbDA3kT6rb4DGIKwEM,1176
|
57
58
|
dv_flow/mgr/yaml_srcinfo_loader.py,sha256=29BNRiB8Hj1FepkrLtdjHSv5U_85Q432gBeeK80nKEA,1606
|
58
59
|
dv_flow/mgr/cmds/cmd_graph.py,sha256=yg5KbNrGvm3dySiI0Qei_pMWZkOE9GtEyaQ4IdNVmoE,2852
|
59
|
-
dv_flow/mgr/cmds/cmd_run.py,sha256=
|
60
|
+
dv_flow/mgr/cmds/cmd_run.py,sha256=SsCZXwutJW1XT5iXtJqvdeg6p6HEa86V5hELNKuaWgA,4082
|
60
61
|
dv_flow/mgr/cmds/cmd_show.py,sha256=JOIFaVXt8YCf9bKXfq6qzV5wQdxdLHqE-yCj0ecGREs,3755
|
61
62
|
dv_flow/mgr/share/flow.json,sha256=lNmZex9NXkYbyb2aZseQfUOkV9CMyfH0iLODEI7EPBw,5096
|
62
63
|
dv_flow/mgr/std/create_file.py,sha256=SEpKTQdiY32002C7b4kYfAiK9v_xajixOJU5WftW75I,2957
|
@@ -73,9 +74,9 @@ dv_flow/mgr/util/util.py,sha256=BO7iqP_c9ttmXkojq7nKDN-g8wl1_Pco9k-KnrXxjwE,1889
|
|
73
74
|
dv_flow/mgr/util/cmds/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
74
75
|
dv_flow/mgr/util/cmds/cmd_schema.py,sha256=IJzZdxCSEgIQ79LpYiM7UqJ9RJ-7yraqmBN2XVgAgXA,1752
|
75
76
|
dv_flow/mgr/util/cmds/cmd_workspace.py,sha256=egmaIXpe5L-TePwmcfisfrG6tdiTUWSjqa9Za5WChVs,890
|
76
|
-
dv_flow_mgr-1.
|
77
|
-
dv_flow_mgr-1.
|
78
|
-
dv_flow_mgr-1.
|
79
|
-
dv_flow_mgr-1.
|
80
|
-
dv_flow_mgr-1.
|
81
|
-
dv_flow_mgr-1.
|
77
|
+
dv_flow_mgr-1.8.14920283751rc0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
78
|
+
dv_flow_mgr-1.8.14920283751rc0.dist-info/METADATA,sha256=CeTzqO-0eYhSYkg9hMV97sS0lr_W_2gulAFrOH5wy_4,13335
|
79
|
+
dv_flow_mgr-1.8.14920283751rc0.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
80
|
+
dv_flow_mgr-1.8.14920283751rc0.dist-info/entry_points.txt,sha256=1roy8wAFM48LabOvr6jiOw0MUs-qE8X3Vf8YykPazxk,50
|
81
|
+
dv_flow_mgr-1.8.14920283751rc0.dist-info/top_level.txt,sha256=amfVTkggzYPtWwLqNmRukfz1Buu0pGS2SrYBBLhXm04,8
|
82
|
+
dv_flow_mgr-1.8.14920283751rc0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
{dv_flow_mgr-1.7.14886019138rc0.dist-info → dv_flow_mgr-1.8.14920283751rc0.dist-info}/top_level.txt
RENAMED
File without changes
|