ATLAS Offline Software
Loading...
Searching...
No Matches
athenaEF_tdaq_infra.Infrastructure Class Reference
Collaboration diagram for athenaEF_tdaq_infra.Infrastructure:

Public Member Functions

 __init__ (self, args)
 __del__ (self)
 register_handlers (self)
 start (self)
 start_rdb (self)
 start_webproxy (self)
 check_alive (self)
 copy_histograms (self)
 dump_is_content (self)
 stop (self)

Public Attributes

 args = args
list processes = []
 pid = os.getpid()
bool ready = False
dict prehandlers = {}

Static Public Attributes

list sigs

Protected Member Functions

 _handle_quit (self, signum, frame)
 _implant_bomb (self)
 _launch (self, name, cmd)

Protected Attributes

 _handle_quit

Detailed Description

Manage the private TDAQ infrastructure (adapted from HLTMPPy.runner.Infrastructure)

Definition at line 95 of file athenaEF_tdaq_infra.py.

Constructor & Destructor Documentation

◆ __init__()

athenaEF_tdaq_infra.Infrastructure.__init__ ( self,
args )

Definition at line 101 of file athenaEF_tdaq_infra.py.

101 def __init__(self, args):
102 self.args = args
103 self.processes = [] # (name, subprocess.Popen)
104 self.pid = os.getpid() # Distinguish mother from children after forking
105 self.ready = False # True once all servers are up
106 self.register_handlers()
107

◆ __del__()

athenaEF_tdaq_infra.Infrastructure.__del__ ( self)
Stop infrastructure in the mother process, in case program exits before stop()

Definition at line 108 of file athenaEF_tdaq_infra.py.

108 def __del__(self):
109 """Stop infrastructure in the mother process, in case program exits before stop()"""
110 if os.getpid() == self.pid:
111 self.stop()
112

Member Function Documentation

◆ _handle_quit()

athenaEF_tdaq_infra.Infrastructure._handle_quit ( self,
signum,
frame )
protected

Definition at line 119 of file athenaEF_tdaq_infra.py.

119 def _handle_quit(self, signum, frame):
120 log.info('Caught signal %d. Cleaning up the infrastructure and exiting', signum)
121 self.stop()
122 prehandler = self.prehandlers.pop(signum, signal.SIG_DFL)
123 signal.signal(signum, prehandler)
124 sys.exit(0)
125

◆ _implant_bomb()

athenaEF_tdaq_infra.Infrastructure._implant_bomb ( self)
protected
preexec_fn ensuring infrastructure processes exit when this process dies

Definition at line 126 of file athenaEF_tdaq_infra.py.

126 def _implant_bomb(self):
127 """preexec_fn ensuring infrastructure processes exit when this process dies"""
128 from ctypes import cdll
129 PR_SET_PDEATHSIG = 1
130 try:
131 return lambda: cdll['libc.so.6'].prctl(PR_SET_PDEATHSIG, signal.SIGKILL)
132 except Exception:
133 log.error('Error setting PR_SET_PDEATHSIG for infrastructure processes. '
134 'Using a dummy function instead')
135 return lambda: 1
136

◆ _launch()

athenaEF_tdaq_infra.Infrastructure._launch ( self,
name,
cmd )
protected

Definition at line 137 of file athenaEF_tdaq_infra.py.

137 def _launch(self, name, cmd):
138 logbase = os.path.join(self.args.log_dir, f'{name}_{self.args.partition}')
139 proc = subprocess.Popen(cmd, preexec_fn=self._implant_bomb(),
140 stdout=open(logbase + '.out', 'w'),
141 stderr=open(logbase + '.err', 'w'),
142 close_fds=True)
143 log.info('Started %s (pid %d): %s', name, proc.pid, ' '.join(cmd))
144 self.processes.append((name, proc))
145 return proc
146

◆ check_alive()

athenaEF_tdaq_infra.Infrastructure.check_alive ( self)
Return False if any infrastructure process has exited

Definition at line 217 of file athenaEF_tdaq_infra.py.

217 def check_alive(self):
218 """Return False if any infrastructure process has exited"""
219 for name, proc in self.processes:
220 ret = proc.poll()
221 if ret is not None:
222 log.error('Infrastructure process %s (pid %d) exited with code %s',
223 name, proc.pid, ret)
224 return False
225 return True
226

◆ copy_histograms()

athenaEF_tdaq_infra.Infrastructure.copy_histograms ( self)

Definition at line 227 of file athenaEF_tdaq_infra.py.

227 def copy_histograms(self):
228 fname = f'r{self.args.run_number:010d}_{self.args.partition}_{self.args.oh_server}.root'
229 log.info('Copying histograms into %s (oh_cp)', fname)
230 subprocess.call(['oh_cp', '-p', self.args.partition, '-s', self.args.oh_server,
231 '-n', '.*', '-o', '.*', '-O',
232 '-r', str(self.args.run_number), '-f', fname])
233

◆ dump_is_content()

athenaEF_tdaq_infra.Infrastructure.dump_is_content ( self)

Definition at line 234 of file athenaEF_tdaq_infra.py.

234 def dump_is_content(self):
235 fname = f'r{self.args.run_number:010d}_{self.args.partition}_DF.txt'
236 log.info('Writing content of DF IS server to %s', fname)
237 with open(fname, "w") as f:
238 subprocess.call(['is_ls', '-p', self.args.partition, '-n', 'DF',
239 '-R', '.*', '-TNv'],
240 stdout=f, stderr=subprocess.STDOUT, text=True)
241

◆ register_handlers()

athenaEF_tdaq_infra.Infrastructure.register_handlers ( self)

Definition at line 113 of file athenaEF_tdaq_infra.py.

113 def register_handlers(self):
114 self.prehandlers = {}
115 for s in self.sigs:
116 self.prehandlers[s] = signal.getsignal(s)
117 signal.signal(s, self._handle_quit)
118

◆ start()

athenaEF_tdaq_infra.Infrastructure.start ( self)

Definition at line 147 of file athenaEF_tdaq_infra.py.

147 def start(self):
148 from ispy import IPCPartition
149
150 partition = self.args.partition
151
152 # Private IPC domain: reference file local to this job's directory
153 ipc_ref = 'file:' + os.path.join(os.getcwd(), 'ipc_init.ref')
154 log.info('Setting TDAQ_IPC_INIT_REF: %s', ipc_ref)
155 os.environ['TDAQ_IPC_INIT_REF'] = ipc_ref
156
157 log.info('Initializing OH monitoring infrastructure for partition %s', partition)
158
159 self._launch('ipc_initial', ['ipc_server'])
160 while not IPCPartition('initial').isValid():
161 log.info('Waiting until initial partition is available...')
162 time.sleep(1)
163
164 self._launch('ipc_partition', ['ipc_server', '-p', partition])
165 while not IPCPartition(partition).isValid():
166 log.info('Waiting until partition %s is available...', partition)
167 time.sleep(1)
168
169 for server in ['DF', 'RunParams', self.args.oh_server]:
170 self._launch(f'is_{server}', ['is_server', '-p', partition, '-n', server])
171
172 self.start_rdb()
173 self.start_webproxy()
174 self.ready = True
175

◆ start_rdb()

athenaEF_tdaq_infra.Infrastructure.start_rdb ( self)
Start rdb_server serving the IS type schema

Definition at line 176 of file athenaEF_tdaq_infra.py.

176 def start_rdb(self):
177 """Start rdb_server serving the IS type schema"""
178 if not self.args.schema:
179 log.info('No --schema given, not starting rdb_server '
180 '(IS publication will be rejected with HTTP 400)')
181 return
182
183 missing = [f for f in self.args.schema if not os.path.exists(f)]
184 if missing:
185 log.error('IS schema file(s) not found: %s', ', '.join(missing))
186 self.stop()
187 sys.exit(1)
188
189 log.info('Starting rdb_server with IS schema: %s', ', '.join(self.args.schema))
190 self._launch('rdb', ['rdb_server', '-p', self.args.partition,
191 '-d', 'ISRepository', '-s',
192 '-D'] + self.args.schema)
193

◆ start_webproxy()

athenaEF_tdaq_infra.Infrastructure.start_webproxy ( self)
Start the webproxy REST server

Definition at line 194 of file athenaEF_tdaq_infra.py.

194 def start_webproxy(self):
195 """Start the webproxy REST server"""
196 port = self.args.webdaq_port
197 webproxy = self._launch('webproxy', ['webproxy', '-p', str(port)])
198
199 timeout = 60
200 for _ in range(timeout):
201 if webproxy.poll() is not None:
202 log.error('webproxy exited early (code %s); see webproxy_%s.err',
203 webproxy.returncode, self.args.partition)
204 self.stop()
205 sys.exit(1)
206 try:
207 with socket.create_connection(('localhost', port), timeout=1):
208 log.info('webproxy listening on http://localhost:%d', port)
209 return
210 except OSError:
211 time.sleep(1)
212
213 log.error('webproxy is not listening on localhost:%d after %d s', port, timeout)
214 self.stop()
215 sys.exit(1)
216

◆ stop()

athenaEF_tdaq_infra.Infrastructure.stop ( self)

Definition at line 242 of file athenaEF_tdaq_infra.py.

242 def stop(self):
243 if not self.processes:
244 return
245
246 if self.ready: # Nothing was ever published if we did not fully start
247 self.copy_histograms()
248 self.dump_is_content()
249
250 log.info('Finalizing OH monitoring infrastructure')
251 for part in [self.args.partition, 'initial']:
252 log.info('Destroying partition: %s', part)
253 subprocess.call(['ipc_rm', '-f', '-p', part, '-i', '".*"', '-n', '".*"'],
254 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
255
256 for name, proc in self.processes:
257 while proc.poll() is None:
258 proc.kill()
259 time.sleep(0.1)
260 self.processes = []
261 log.info('Terminated all infrastructure processes')
262
263

Member Data Documentation

◆ _handle_quit

athenaEF_tdaq_infra.Infrastructure._handle_quit
protected

Definition at line 117 of file athenaEF_tdaq_infra.py.

◆ args

athenaEF_tdaq_infra.Infrastructure.args = args

Definition at line 102 of file athenaEF_tdaq_infra.py.

◆ pid

athenaEF_tdaq_infra.Infrastructure.pid = os.getpid()

Definition at line 104 of file athenaEF_tdaq_infra.py.

◆ prehandlers

dict athenaEF_tdaq_infra.Infrastructure.prehandlers = {}

Definition at line 114 of file athenaEF_tdaq_infra.py.

◆ processes

list athenaEF_tdaq_infra.Infrastructure.processes = []

Definition at line 103 of file athenaEF_tdaq_infra.py.

◆ ready

bool athenaEF_tdaq_infra.Infrastructure.ready = False

Definition at line 105 of file athenaEF_tdaq_infra.py.

◆ sigs

list athenaEF_tdaq_infra.Infrastructure.sigs
static
Initial value:
= [signal.SIGFPE, signal.SIGHUP, signal.SIGQUIT, signal.SIGSEGV,
signal.SIGTERM, signal.SIGINT]

Definition at line 98 of file athenaEF_tdaq_infra.py.


The documentation for this class was generated from the following file: