aegis_gui.utilities.sim_tracker

  1import dash
  2from aegis_sim.utilities.container import Container
  3from aegis_gui.utilities import utilities
  4import dash_bootstrap_components as dbc
  5from aegis_gui.utilities import log
  6from aegis_gui.guisettings.GuiSettings import gui_settings
  7
  8
  9def make_trackers(ticker_store):
 10    trackers = []
 11
 12    running_sims = []
 13    paths = utilities.get_sim_paths()
 14    for path in paths:
 15
 16        ticker_store_status = ticker_store.get(path.stem)
 17        ticker_registered_and_finished = ticker_store_status is False
 18        if ticker_registered_and_finished:
 19            continue
 20
 21        container = Container(path)
 22        is_running = not container.has_ticker_stopped()
 23        ticker_store[path.stem] = is_running
 24        if is_running:
 25            progress = container.get_simple_log()
 26            if progress is None:
 27                continue
 28            progress = progress[0] / progress[1]
 29            progressbar = dbc.Progress(
 30                label=container.name,
 31                value=10 + progress * 90,
 32                striped=True,
 33                animated=True,
 34                style={"marginTop": "0.5rem"},
 35            )
 36            linked_progressbar = dash.dcc.Link(
 37                children=progressbar,
 38                href=gui_settings.wrap_href(f"simlog?sim={container.name}"),
 39            )
 40            # running_sims.append(tracker)
 41            running_sims.append(linked_progressbar)
 42
 43    if running_sims:
 44        trackers.append(
 45            dbc.Toast(
 46                children=[
 47                    # dash.html.Hr(),
 48                    # dash.html.P("Running simulations", className="text-secondary", style={"margin": 0}),
 49                ]
 50                + running_sims,
 51                header="Running sims",
 52                style={"width": "100%", "marginTop": "1rem"},
 53            )
 54        )
 55
 56    recent_containers = []
 57
 58    RECENCY_WINDOW = 365 * 24 * 3600
 59
 60    for path in paths:
 61        container = Container(path)
 62        ticker = container.get_ticker()
 63        since_last = ticker.since_last()
 64        if since_last is None:
 65            continue
 66        if since_last < RECENCY_WINDOW and container.has_ticker_stopped():
 67            recent_containers.append(container)
 68
 69    if recent_containers:
 70        N_recent_containers_to_show = 20
 71
 72        buttons = [
 73            dbc.Button(
 74                children=[rc.name],
 75                href=gui_settings.wrap_href(f"simlog?sim={rc.name}"),
 76                className="badge me-1",
 77                color="primary",
 78            )
 79            for rc in recent_containers[:N_recent_containers_to_show]
 80        ]
 81
 82        if len(recent_containers) > N_recent_containers_to_show:
 83            buttons.append(
 84                dbc.Button("more...", className="badge me-1", color="secondary", href=gui_settings.wrap_href(f"simlog"))
 85            )
 86
 87        nav = dash.html.Div(children=buttons)
 88
 89        trackers.append(
 90            dbc.Toast(
 91                children=nav,
 92                header="Most recent sims",
 93                style={"width": "100%", "marginTop": "1rem"},
 94            )
 95        )
 96
 97        # trackers.append(nav)
 98
 99    return trackers, ticker_store
100
101
102@log.log_debug
103def init_tracker_box():
104    trackers, ticker_store = get_tracker_box(None, {})
105    return [
106        dash.dcc.Interval(
107            id="running-simulations-interval", interval=2 * 1000, n_intervals=0
108        ),  # TODO potential performance issues
109        dash.dcc.Store(id="ticker-store", data=ticker_store),
110        dash.html.Div(trackers, id="running-simulations"),
111    ]
112
113
114@dash.callback(
115    dash.Output("running-simulations", "children"),
116    dash.Output("ticker-store", "data"),
117    dash.Input("running-simulations-interval", "n_intervals"),
118    dash.State("ticker-store", "data"),
119)
120def get_tracker_box(n, ticker_store):
121    # NOTE This takes a long time. If the interval refresh rate is very high, it will be retriggered before finishing and no trackers will appear.
122    trackers, ticker_store = make_trackers(ticker_store)
123    return trackers, ticker_store
def make_trackers(ticker_store):
 10def make_trackers(ticker_store):
 11    trackers = []
 12
 13    running_sims = []
 14    paths = utilities.get_sim_paths()
 15    for path in paths:
 16
 17        ticker_store_status = ticker_store.get(path.stem)
 18        ticker_registered_and_finished = ticker_store_status is False
 19        if ticker_registered_and_finished:
 20            continue
 21
 22        container = Container(path)
 23        is_running = not container.has_ticker_stopped()
 24        ticker_store[path.stem] = is_running
 25        if is_running:
 26            progress = container.get_simple_log()
 27            if progress is None:
 28                continue
 29            progress = progress[0] / progress[1]
 30            progressbar = dbc.Progress(
 31                label=container.name,
 32                value=10 + progress * 90,
 33                striped=True,
 34                animated=True,
 35                style={"marginTop": "0.5rem"},
 36            )
 37            linked_progressbar = dash.dcc.Link(
 38                children=progressbar,
 39                href=gui_settings.wrap_href(f"simlog?sim={container.name}"),
 40            )
 41            # running_sims.append(tracker)
 42            running_sims.append(linked_progressbar)
 43
 44    if running_sims:
 45        trackers.append(
 46            dbc.Toast(
 47                children=[
 48                    # dash.html.Hr(),
 49                    # dash.html.P("Running simulations", className="text-secondary", style={"margin": 0}),
 50                ]
 51                + running_sims,
 52                header="Running sims",
 53                style={"width": "100%", "marginTop": "1rem"},
 54            )
 55        )
 56
 57    recent_containers = []
 58
 59    RECENCY_WINDOW = 365 * 24 * 3600
 60
 61    for path in paths:
 62        container = Container(path)
 63        ticker = container.get_ticker()
 64        since_last = ticker.since_last()
 65        if since_last is None:
 66            continue
 67        if since_last < RECENCY_WINDOW and container.has_ticker_stopped():
 68            recent_containers.append(container)
 69
 70    if recent_containers:
 71        N_recent_containers_to_show = 20
 72
 73        buttons = [
 74            dbc.Button(
 75                children=[rc.name],
 76                href=gui_settings.wrap_href(f"simlog?sim={rc.name}"),
 77                className="badge me-1",
 78                color="primary",
 79            )
 80            for rc in recent_containers[:N_recent_containers_to_show]
 81        ]
 82
 83        if len(recent_containers) > N_recent_containers_to_show:
 84            buttons.append(
 85                dbc.Button("more...", className="badge me-1", color="secondary", href=gui_settings.wrap_href(f"simlog"))
 86            )
 87
 88        nav = dash.html.Div(children=buttons)
 89
 90        trackers.append(
 91            dbc.Toast(
 92                children=nav,
 93                header="Most recent sims",
 94                style={"width": "100%", "marginTop": "1rem"},
 95            )
 96        )
 97
 98        # trackers.append(nav)
 99
100    return trackers, ticker_store
@dash.callback(dash.Output('running-simulations', 'children'), dash.Output('ticker-store', 'data'), dash.Input('running-simulations-interval', 'n_intervals'), dash.State('ticker-store', 'data'))
def get_tracker_box(n, ticker_store):
115@dash.callback(
116    dash.Output("running-simulations", "children"),
117    dash.Output("ticker-store", "data"),
118    dash.Input("running-simulations-interval", "n_intervals"),
119    dash.State("ticker-store", "data"),
120)
121def get_tracker_box(n, ticker_store):
122    # NOTE This takes a long time. If the interval refresh rate is very high, it will be retriggered before finishing and no trackers will appear.
123    trackers, ticker_store = make_trackers(ticker_store)
124    return trackers, ticker_store