Skip to content

Commit

Permalink
Add indicator column to show active tasks
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelldls committed Oct 22, 2024
1 parent 96b2e53 commit 4418863
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 9 deletions.
56 changes: 47 additions & 9 deletions src/edge_containers_cli/cmds/monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from textual.widgets.data_table import RowKey

from edge_containers_cli.cmds.commands import Commands
from edge_containers_cli.definitions import ECLogLevels
from edge_containers_cli.definitions import ECLogLevels, emoji
from edge_containers_cli.logging import log


Expand Down Expand Up @@ -212,22 +212,50 @@ def __init__(self, commands, running_only: bool) -> None:
self.refresh_rate = 10
self.commands = commands
self.running_only = running_only
self.iocs_df = self.commands._get_services(self.running_only) # noqa: SLF001
self._indicator_lock = asyncio.Lock()
self._service_indicators = {
"name": [""],
emoji.exclaim: [""],
}
self.iocs_df = self._get_services_df(running_only)

self._polling = True
self._get_iocs()
self._polling_task = asyncio.create_task(
self._poll_services()
) # https://github.com/Textualize/textual/discussions/1828

def _get_services_df(self, running_only):
services_df = self.commands._get_services(running_only) # noqa: SLF001
services_df = services_df.with_columns(
polars.when(polars.col("ready"))
.then(polars.lit(emoji.check_mark))
.otherwise(polars.lit(emoji.cross_mark))
.alias("ready")
)
indicators_df = polars.DataFrame(self._service_indicators)
result = services_df.join(indicators_df, on="name", how="left").fill_null("")
return result

async def _poll_services(self):
while self._polling:
self.iocs_df = await asyncio.to_thread(
self.commands._get_services, # noqa: SLF001
self._get_services_df, # noqa: SLF001
self.running_only,
)
await asyncio.sleep(1.0)

async def update_indicators(self, name: str, indicator: str):
"""Update indicators in a concurrecy-safe manner"""
async with self._indicator_lock:
if name in self._service_indicators["name"]:
index = self._service_indicators["name"].index(name)
self._service_indicators[emoji.exclaim][index] = indicator
else:
self._service_indicators["name"].append(name)
self._service_indicators[emoji.exclaim].append(indicator)
log.info("Exited")

def stop(self):
self._polling = False

Expand Down Expand Up @@ -275,7 +303,10 @@ def _get_heading(self, column_id: str):

def compose(self) -> ComposeResult:
table: DataTable[Text] = DataTable(
id="body_table", header_height=1, show_cursor=False, zebra_stripes=True
id="body_table",
header_height=1,
show_cursor=False,
zebra_stripes=True,
)
table.focus()

Expand Down Expand Up @@ -330,7 +361,10 @@ async def populate_table(self) -> None:
{
"col_key": key,
"contents": SortableText(
ioc[key], str(ioc[key]), self._get_color(str(ioc[key]))
ioc[key],
str(ioc[key]),
self._get_color(str(ioc[key])),
justify="center",
),
}
for key in self.columns
Expand Down Expand Up @@ -457,10 +491,14 @@ def _get_service_name(self) -> str:

def _do_confirmed_action(self, action: str, command: Callable):
service_name = self._get_service_name()
table = self.query_one(IocTable)

def task_done_callback(t):
"""Called when asyncio task is completed."""
async def for_task(command, service_name):
"""Called to start asyncio to_thread task."""
await table.update_indicators(service_name, emoji.road_works)
await asyncio.to_thread(command, service_name)
del self.busy_services[service_name]
await table.update_indicators(service_name, emoji.none)

def after_dismiss_callback(start: bool | None) -> None:
"""Called when ConfirmScreen is dismissed."""
Expand All @@ -470,11 +508,10 @@ def after_dismiss_callback(start: bool | None) -> None:
return None
else:
task = asyncio.create_task(
asyncio.to_thread(command, service_name),
for_task(command, service_name),
name=service_name,
)
self.busy_services[service_name] = task
task.add_done_callback(task_done_callback)

self.push_screen(ConfirmScreen(service_name, action), after_dismiss_callback)

Expand Down Expand Up @@ -525,4 +562,5 @@ def action_monitor_logs(self) -> None:
def update_sort_key(self, col_name: str) -> None:
"""Method called to update the table sort key attribute."""
table = self.query_one(IocTable)
log.info(f"New sort key '{col_name}'")
table.sort_column_id = col_name
8 changes: 8 additions & 0 deletions src/edge_containers_cli/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,11 @@ class ECContext:
repo: str = ""
target: str = ""
log_url: str = ""


class emoji(str, Enum):
none = ""
road_works = "\U0001f6a7"
exclaim = "\U00002755"
check_mark = "\U00002705"
cross_mark = "\U0000274c"

0 comments on commit 4418863

Please sign in to comment.