Skip to content

Commit 2de403a

Browse files
authored
RF: migas updates (#230)
* ENH: Strip out telemetry functions into dedicated module * RF: Simplify telemetry communication * RF: Remove `notrack` catch, do not set default for process status
1 parent a55aadd commit 2de403a

File tree

3 files changed

+62
-43
lines changed

3 files changed

+62
-43
lines changed

nibabies/cli/run.py

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
"""NiBabies runner."""
44
from .. import config
55

6+
EXITCODE: int = -1
7+
68

79
def main():
810
"""Entry point."""
@@ -13,7 +15,7 @@ def main():
1315
from pathlib import Path
1416

1517
from ..utils.bids import write_bidsignore, write_derivative_description
16-
from ..utils.misc import ping_migas
18+
from ..utils.telemetry import setup_migas
1719
from .parser import parse_args
1820
from .workflow import build_boilerplate, build_workflow
1921

@@ -23,9 +25,12 @@ def main():
2325

2426
parse_args()
2527

26-
# collect telemetry information - if `--notrack` is specified,
27-
# nothing is sent.
28-
ping_migas()
28+
# collect and submit telemetry information
29+
# if `--notrack` is specified, nothing is done.
30+
global EXITCODE
31+
if not config.execution.notrack:
32+
setup_migas(init_ping=True)
33+
atexit.register(_migas_exit)
2934

3035
if "participant" in config.workflow.analysis_level:
3136
_pool = None
@@ -55,27 +60,27 @@ def main():
5560
# build the workflow within the same process
5661
# it still needs to be saved / loaded to be properly initialized
5762
retval = build_workflow(config_file)
58-
retcode = retval['return_code']
63+
EXITCODE = retval['return_code']
5964
nibabies_wf = retval['workflow']
6065

61-
if nibabies_wf is None:
62-
ping_migas(status='error')
63-
if config.execution.reports_only:
64-
sys.exit(int(retcode > 0))
65-
sys.exit(os.EX_SOFTWARE)
66+
# exit conditions:
67+
# - no workflow (--reports-only)
68+
# - retcode is not 0
69+
# - boilerplate only
70+
71+
if nibabies_wf is None and not config.execution.reports_only:
72+
sys.exit(EXITCODE)
6673

6774
if config.execution.write_graph:
6875
nibabies_wf.write_graph(graph2use="colored", format="svg", simple_form=True)
6976

70-
if retcode != 0:
71-
ping_migas(status='error')
72-
sys.exit(retcode)
77+
if EXITCODE != 0:
78+
sys.exit(EXITCODE)
7379

7480
# generate boilerplate
7581
build_boilerplate(nibabies_wf)
7682
if config.execution.boilerplate_only:
77-
ping_migas(status='success')
78-
sys.exit(0)
83+
sys.exit(EXITCODE)
7984

8085
gc.collect()
8186

@@ -99,13 +104,12 @@ def main():
99104
nibabies_wf.run(**_plugin)
100105
except Exception as e:
101106
config.loggers.workflow.critical("nibabies failed: %s", e)
102-
ping_migas(status='error')
107+
EXITCODE = 1
103108
raise
104109
else:
105110
config.loggers.workflow.log(25, "nibabies finished successfully!")
106111
# Bother users with the boilerplate only iff the workflow went okay.
107112
boiler_file = config.execution.nibabies_dir / "logs" / "CITATION.md"
108-
ping_migas(status='success')
109113
if boiler_file.exists():
110114
if config.environment.exec_env in (
111115
"singularity",
@@ -147,6 +151,20 @@ def main():
147151
write_bidsignore(config.execution.nibabies_dir)
148152

149153

154+
def _migas_exit() -> None:
155+
"""
156+
Send a final crumb to the migas server signaling if the run successfully completed
157+
158+
This function is registered with `atexit` to run at termination.
159+
"""
160+
global EXITCODE
161+
status = 'error' if EXITCODE > 0 else 'success'
162+
163+
from ..utils.telemetry import ping_migas
164+
165+
ping_migas(status=status)
166+
167+
150168
if __name__ == "__main__":
151169
raise RuntimeError(
152170
"Please `pip install` this and run via the commandline interfaces, `nibabies <command>`"

nibabies/utils/misc.py

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -113,29 +113,3 @@ def combine_meepi_source(in_files):
113113
entities = [ent for ent in in_file.split("_") if not ent.startswith("echo-")]
114114
basename = "_".join(entities)
115115
return os.path.join(base, basename)
116-
117-
118-
def ping_migas(status='pending'):
119-
"""Communicate with the migas telemetry server."""
120-
import os
121-
122-
import migas
123-
124-
from ..config import execution
125-
126-
if execution.notrack:
127-
return
128-
129-
os.environ['ENABLE_MIGAS'] = 'yes'
130-
session_id = None
131-
if execution.run_uuid:
132-
session_id = execution.run_uuid.split('_')[1]
133-
134-
# TODO: check for bad versions
135-
res = migas.add_project(
136-
project="nipreps/nibabies",
137-
project_version=__version__,
138-
status=status,
139-
session_id=session_id, # uuid
140-
)
141-
return res

nibabies/utils/telemetry.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import migas
2+
3+
from .. import __version__, config
4+
5+
6+
def setup_migas(init_ping: bool = True) -> None:
7+
"""
8+
Prepare the migas python client to communicate with a migas server.
9+
If `init_ping` is `True`, send an initial breadcrumb.
10+
"""
11+
# generate session UUID from generated run UUID
12+
session_id = None
13+
if config.execution.run_uuid:
14+
session_id = config.execution.run_uuid.split('_', 1)[-1]
15+
16+
migas.setup(session_id=session_id)
17+
if init_ping:
18+
# send initial status ping
19+
ping_migas(status='pending')
20+
21+
22+
def ping_migas(*, status: str) -> dict:
23+
"""
24+
Communicate with the migas telemetry server. This requires `migas.setup()` to be called.
25+
"""
26+
res = migas.add_project("nipreps/nibabies", __version__, status=status)
27+
return res

0 commit comments

Comments
 (0)