Skip to content

Commit

Permalink
Handle failed process status notification in results panels
Browse files Browse the repository at this point in the history
  • Loading branch information
edan-bainglass committed Nov 17, 2024
1 parent cc7ceb5 commit 4380a7b
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 37 deletions.
39 changes: 25 additions & 14 deletions src/aiidalab_qe/common/panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,14 @@ class ResultsModel(Model, HasProcess):
title = "Model"
identifier = "model"

process_state_notification = tl.Unicode("")
process_status_notification = tl.Unicode("")

_this_process_label = ""
_this_process_uuid = None

CSS_MAP = {
"finished": "success",
"failed": "danger",
"excepted": "danger",
"killed": "danger",
"queued": "warning",
Expand All @@ -210,19 +211,28 @@ def has_results(self):
node = self._fetch_child_process_node()
return node and node.is_finished_ok

@property
def process_state(self):
node = self._fetch_child_process_node()
return node.process_state.value if node and node.process_state else "queued"
def update_process_status_notification(self):
self.process_status_notification = self._get_child_process_status()

def update_process_state_notification(self):
state = self.process_state
self.process_state_notification = f"""
def _get_child_process_status(self, child="this"):
state, exit_message = self._get_child_state_and_exit_message(child)
status = state.upper()
if exit_message:
status = f"{status} ({exit_message})"
label = "Status" if child == "this" else f"{child.capitalize()} status"
return f"""
<div class="alert alert-{self.CSS_MAP.get(state, "info")}">
<b>Status:</b> {state.upper()}
<b>{label}:</b> {status}
</div>
"""

def _get_child_state_and_exit_message(self, child="this"):
if not (node := self._fetch_child_process_node(child)):
return "queued", None
if node.is_failed:
return "failed", node.exit_message
return node.process_state.value, None

def _get_child_outputs(self, child="this"):
if not (node := self._fetch_child_process_node(child)):
outputs = super().outputs
Expand All @@ -233,6 +243,7 @@ def _get_child_outputs(self, child="this"):
def _fetch_child_process_node(self, child="this") -> orm.ProcessNode | None:
if not self.process_uuid:
return
child = child.lower()
uuid = getattr(self, f"_{child}_process_uuid")
label = getattr(self, f"_{child}_process_label")
if not uuid:
Expand Down Expand Up @@ -288,10 +299,10 @@ def __init__(self, model: RM, **kwargs):

self.links = []

self.process_state_notification = ipw.HTML()
self.process_status_notification = ipw.HTML()
ipw.dlink(
(self._model, "process_state_notification"),
(self.process_state_notification, "value"),
(self._model, "process_status_notification"),
(self.process_status_notification, "value"),
)

self.load_results_button = ipw.Button(
Expand All @@ -309,7 +320,7 @@ def __init__(self, model: RM, **kwargs):

super().__init__(
children=[
self.process_state_notification,
self.process_status_notification,
ipw.HBox(
children=[
self.load_results_button,
Expand All @@ -332,4 +343,4 @@ def _on_load_results_click(self, _):
self.render()

def _on_monitor_counter_change(self, _):
self._model.update_process_state_notification()
self._model.update_process_status_notification()
28 changes: 5 additions & 23 deletions src/aiidalab_qe/plugins/electronic_structure/result/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# TODO reduce to a container of Bands and PDOS, similar to its results panel
class ElectronicStructureResultsModel(ResultsModel):
identifier = "electronic_structure"
identifiers = ("bands", "pdos")

_bands_process_label = "BandsWorkChain"
_bands_process_uuid = None
Expand All @@ -30,34 +31,15 @@ def get_bands_node(self):

@property
def include(self):
return all(identifier in self.properties for identifier in ("bands", "pdos"))
return all(identifier in self.properties for identifier in self.identifiers)

@property
def has_results(self):
# TODO should be `or` if merged
return self._has_bands and self._has_pdos

@property
def process_states(self):
return [
node.process_state.value if node and node.process_state else "queued"
for node in (
self._fetch_child_process_node("bands"),
self._fetch_child_process_node("pdos"),
)
]

def update_process_state_notification(self):
processes = ("Bands", "PDOS")
states = self.process_states
self.process_state_notification = "\n".join(
f"""
<div class="alert alert-{self.CSS_MAP.get(state, "info")}">
<b>{process} status:</b> {state.upper()}
</div>
"""
for process, state in zip(processes, states)
)
def update_process_status_notification(self):
statuses = [self._get_child_process_status(child) for child in self.identifiers]
self.process_status_notification = "\n".join(statuses)

@property
def _has_bands(self):
Expand Down

0 comments on commit 4380a7b

Please sign in to comment.