Add queue details view
This commit is contained in:
@@ -7,7 +7,7 @@ from app import dp
|
|||||||
from auth import is_admin_msg
|
from auth import is_admin_msg
|
||||||
from keyboards import backup_kb
|
from keyboards import backup_kb
|
||||||
from lock_utils import acquire_lock, release_lock
|
from lock_utils import acquire_lock, release_lock
|
||||||
from services.queue import enqueue, format_status
|
from services.queue import enqueue, format_status, format_details
|
||||||
from services.backup import backup_badge, restore_help
|
from services.backup import backup_badge, restore_help
|
||||||
from services.runner import run_cmd
|
from services.runner import run_cmd
|
||||||
|
|
||||||
@@ -250,6 +250,12 @@ async def qb(msg: Message):
|
|||||||
await msg.answer(format_status(), reply_markup=backup_kb)
|
await msg.answer(format_status(), reply_markup=backup_kb)
|
||||||
|
|
||||||
|
|
||||||
|
@dp.message(F.text == "🧾 Queue details")
|
||||||
|
async def qd(msg: Message):
|
||||||
|
if is_admin_msg(msg):
|
||||||
|
await msg.answer(format_details(), reply_markup=backup_kb)
|
||||||
|
|
||||||
|
|
||||||
@dp.message(F.text == "▶️ Run backup")
|
@dp.message(F.text == "▶️ Run backup")
|
||||||
async def br(msg: Message):
|
async def br(msg: Message):
|
||||||
if is_admin_msg(msg):
|
if is_admin_msg(msg):
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ backup_kb = ReplyKeyboardMarkup(
|
|||||||
keyboard=[
|
keyboard=[
|
||||||
[KeyboardButton(text="📦 Status"), KeyboardButton(text="📦 Last snapshot")],
|
[KeyboardButton(text="📦 Status"), KeyboardButton(text="📦 Last snapshot")],
|
||||||
[KeyboardButton(text="📊 Repo stats"), KeyboardButton(text="🧯 Restore help")],
|
[KeyboardButton(text="📊 Repo stats"), KeyboardButton(text="🧯 Restore help")],
|
||||||
[KeyboardButton(text="▶️ Run backup"), KeyboardButton(text="🧾 Queue")],
|
[KeyboardButton(text="▶️ Run backup"), KeyboardButton(text="🧾 Queue"), KeyboardButton(text="🧾 Queue details")],
|
||||||
[KeyboardButton(text="🧪 Restic check"), KeyboardButton(text="📬 Weekly report"), KeyboardButton(text="⬅️ Назад")],
|
[KeyboardButton(text="🧪 Restic check"), KeyboardButton(text="📬 Weekly report"), KeyboardButton(text="⬅️ Назад")],
|
||||||
],
|
],
|
||||||
resize_keyboard=True,
|
resize_keyboard=True,
|
||||||
|
|||||||
@@ -1,34 +1,58 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
from typing import Awaitable, Callable
|
import time
|
||||||
|
from typing import Awaitable, Callable, Any
|
||||||
|
|
||||||
|
|
||||||
_queue: asyncio.Queue = asyncio.Queue()
|
_queue: asyncio.Queue = asyncio.Queue()
|
||||||
_current_label: str | None = None
|
_current_label: str | None = None
|
||||||
|
_current_meta: dict[str, Any] | None = None
|
||||||
|
|
||||||
|
|
||||||
async def enqueue(label: str, job: Callable[[], Awaitable[None]]) -> int:
|
async def enqueue(label: str, job: Callable[[], Awaitable[None]]) -> int:
|
||||||
await _queue.put((label, job))
|
await _queue.put((label, job, time.time()))
|
||||||
return _queue.qsize()
|
return _queue.qsize()
|
||||||
|
|
||||||
|
|
||||||
async def worker():
|
async def worker():
|
||||||
global _current_label
|
global _current_label, _current_meta
|
||||||
while True:
|
while True:
|
||||||
label, job = await _queue.get()
|
label, job, enqueued_at = await _queue.get()
|
||||||
_current_label = label
|
_current_label = label
|
||||||
|
_current_meta = {"enqueued_at": enqueued_at, "started_at": time.time()}
|
||||||
try:
|
try:
|
||||||
await job()
|
await job()
|
||||||
finally:
|
finally:
|
||||||
_current_label = None
|
_current_label = None
|
||||||
|
_current_meta = None
|
||||||
_queue.task_done()
|
_queue.task_done()
|
||||||
|
|
||||||
|
|
||||||
def format_status() -> str:
|
def format_status() -> str:
|
||||||
pending = [label for label, _ in list(_queue._queue)]
|
pending = list(_queue._queue)
|
||||||
lines = ["🧾 Queue"]
|
lines = ["🧾 Queue"]
|
||||||
lines.append(f"🔄 Running: {_current_label or 'idle'}")
|
lines.append(f"🔄 Running: {_current_label or 'idle'}")
|
||||||
lines.append(f"⏳ Pending: {len(pending)}")
|
lines.append(f"⏳ Pending: {len(pending)}")
|
||||||
if pending:
|
if pending:
|
||||||
preview = ", ".join(pending[:5])
|
preview = ", ".join([p[0] for p in pending[:5]])
|
||||||
lines.append(f"➡️ Next: {preview}")
|
lines.append(f"➡️ Next: {preview}")
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
|
def format_details(limit: int = 10) -> str:
|
||||||
|
now = time.time()
|
||||||
|
lines = ["🧾 Queue details"]
|
||||||
|
if _current_label:
|
||||||
|
started_at = _current_meta.get("started_at") if _current_meta else None
|
||||||
|
runtime = f"{int(now - started_at)}s" if started_at else "n/a"
|
||||||
|
lines.append(f"🔄 Running: {_current_label} ({runtime})")
|
||||||
|
else:
|
||||||
|
lines.append("🔄 Running: idle")
|
||||||
|
|
||||||
|
pending = list(_queue._queue)
|
||||||
|
lines.append(f"⏳ Pending: {len(pending)}")
|
||||||
|
if pending:
|
||||||
|
lines.append("🔢 Position | Label | Wait")
|
||||||
|
for i, (label, _job, enqueued_at) in enumerate(pending[:limit], start=1):
|
||||||
|
wait = int(now - enqueued_at)
|
||||||
|
lines.append(f"{i:>3} | {label} | {wait}s")
|
||||||
|
return "\n".join(lines)
|
||||||
|
|||||||
Reference in New Issue
Block a user