DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
multiprocess_runcontrol_driver Namespace Reference

Functions

 read_stream (stream, process_name, completion_event)
 interactive_manager (commands)

Variables

int last_msg_time = 0
 pm_port = find_free_port(50001, 52000)
list interactive_cmds

Function Documentation

◆ interactive_manager()

interactive_manager ( commands)

Definition at line 47 of file multiprocess_runcontrol_driver.py.

47async def interactive_manager(commands):
48 processes = {}
49 tasks = []
50 command_completion_event = asyncio.Event()
51 global last_msg_time
52
53 # 1. Start all interactive subprocesses
54 for cmd in commands:
55 name = cmd.pop(0)
56 print()
57 print(f"*** Starting \"{cmd[0]}\" with local process name \"{name}\"...")
58 print()
59 proc = await asyncio.create_subprocess_exec(
60 *cmd,
61 stdin=asyncio.subprocess.PIPE,
62 stdout=asyncio.subprocess.PIPE,
63 stderr=asyncio.subprocess.STDOUT
64 )
65 processes[name] = proc
66
67 # 2. Schedule output reading tasks concurrently
68 tasks.append(asyncio.create_task(read_stream(proc.stdout, name, command_completion_event)))
69
70 time.sleep(2)
71
72 print()
73 print(f"*** Started {len(processes)} processes. Type: '<process_name>:<input>' (e.g., shell:help)")
74 print("*** Type 'exit' to quit everything.")
75 print()
76
77 # 3. Handle interactive user input from the main terminal
78 loop = asyncio.get_running_loop()
79 reader = asyncio.StreamReader()
80 protocol = asyncio.StreamReaderProtocol(reader)
81 await loop.connect_read_pipe(lambda: protocol, sys.stdin)
82
83 try:
84 while True:
85 print("\nmprc_drvr> ", end="", flush=True)
86 user_line = await reader.readline()
87 if not user_line:
88 break
89
90 command_text = user_line.decode().strip()
91 if command_text.lower() == 'exit':
92 break
93
94 # Parse target process and message (Format: Proc-1:your_command)
95 if ":" in command_text:
96 target, msg = command_text.split(":", 1)
97 target = target.strip()
98
99 if target in processes:
100 proc = processes[target]
101 if proc.returncode is None: # Check if still running
102 cmd_start_time = time.time()
103 proc.stdin.write((msg + "\n").encode())
104 await proc.stdin.drain()
105 print(f"[System] Sent to {target}: {msg}")
106 if "drunc" in target:
107 proc.stdin.write(("echo '*** COMMAND HAS COMPLETED ***'\n").encode())
108 await proc.stdin.drain()
109 print(f"[System] Sent to {target}: echo '*** COMMAND HAS COMPLETED ***'")
110 await command_completion_event.wait()
111 command_completion_event.clear()
112 else:
113 now = time.time()
114 while True:
115 if last_msg_time <= cmd_start_time:
116 if now - cmd_start_time > 5:
117 break
118 else:
119 if now - last_msg_time >= 5:
120 break
121 await asyncio.sleep(0.25)
122 now = time.time()
123 else:
124 print(f"[System] Error: {target} has already exited.")
125 else:
126 print(f"[System] Error: Process '{target}' not found.")
127 else:
128 print("[System] Invalid format. Use: <process_name>:<command>")
129
130 except asyncio.CancelledError:
131 pass
132 finally:
133 # 4. Cleanup and terminate remaining processes
134 print("\n[System] Shutting down processes...")
135 for name, proc in reversed(processes.items()):
136 if proc.returncode is None:
137 proc.terminate()
138 await proc.wait()
139
140 # Cancel background reading tasks
141 for task in tasks:
142 task.cancel()
143

◆ read_stream()

read_stream ( stream,
process_name,
completion_event )
Asynchronously reads lines from a stream and prints them immediately.

Definition at line 30 of file multiprocess_runcontrol_driver.py.

30async def read_stream(stream, process_name, completion_event):
31 """Asynchronously reads lines from a stream and prints them immediately."""
32 global last_msg_time
33 while True:
34 line = await stream.readline()
35 if not line:
36 break
37 decoded_line = line.decode().rstrip()
38
39 if "*** COMMAND HAS COMPLETED ***" in decoded_line:
40 completion_event.set()
41 continue
42
43 # Decode and strip line endings
44 print(f"[{process_name}] {line.decode().rstrip()}", flush=True)
45 last_msg_time = time.time()
46

Variable Documentation

◆ interactive_cmds

list multiprocess_runcontrol_driver.interactive_cmds
Initial value:
= [
["pm", "drunc-process-manager", "ssh-standalone", str(pm_port)],
["pmshell", "drunc-process-manager-shell", f"grpc://localhost:{pm_port}"],
["drunc", "drunc-unified-shell", f"grpc://localhost:{pm_port}", "config/daqsystemtest/example-configs.data.xml", "local-1x1-config", "biery-local-test"]
]

Definition at line 152 of file multiprocess_runcontrol_driver.py.

◆ last_msg_time

int multiprocess_runcontrol_driver.last_msg_time = 0

Definition at line 28 of file multiprocess_runcontrol_driver.py.

◆ pm_port

multiprocess_runcontrol_driver.pm_port = find_free_port(50001, 52000)

Definition at line 145 of file multiprocess_runcontrol_driver.py.