swap threading for multiprocessing's ThreadPool (radio playlist load), aiosqlite -> sqlite3 standard lib as disk i/o is blocking regardless; changes related to #32 for radio queue pagination, more work needed

This commit is contained in:
2025-04-26 12:01:45 -04:00
parent 6502199b5d
commit 4c5d2b6943
3 changed files with 157 additions and 127 deletions

View File

@ -2,8 +2,7 @@ import logging
import traceback
import time
import random
import asyncio
import threading
from multiprocessing.pool import ThreadPool as Pool
from .constructors import (
ValidRadioNextRequest,
ValidRadioReshuffleRequest,
@ -11,10 +10,9 @@ from .constructors import (
ValidRadioQueueRemovalRequest,
ValidRadioSongRequest,
ValidRadioTypeaheadRequest,
ValidRadioQueueRequest,
)
from utils import radio_util
from uuid import uuid4 as uuid
from typing import Optional
from fastapi import FastAPI, BackgroundTasks, Request, Response, HTTPException
from fastapi.responses import RedirectResponse, JSONResponse
@ -59,12 +57,10 @@ class Radio(FastAPI):
async def on_start(self) -> None:
logging.info("radio: Initializing")
thread = threading.Thread(
target=asyncio.run, args=(self.radio_util.load_playlist(),)
)
thread.start()
# await self.radio_util.load_playlist()
await self.radio_util._ls_skip()
with Pool() as pool:
res = pool.apply_async(self.radio_util.load_playlist)
if res:
await self.radio_util._ls_skip()
async def radio_skip(
self, data: ValidRadioNextRequest, request: Request
@ -101,6 +97,8 @@ class Radio(FastAPI):
},
)
except Exception as e:
logging.debug("radio_skip Exception: %s",
str(e))
traceback.print_exc()
return JSONResponse(
status_code=500,
@ -124,18 +122,23 @@ class Radio(FastAPI):
return JSONResponse(content={"ok": True})
async def radio_get_queue(
self, request: Request, limit: Optional[int] = 15_000
self, request: Request, data: ValidRadioQueueRequest,
) -> JSONResponse:
"""
Get current play queue, up to limit [default: 15k]
- **limit**: Number of queue items to return, default 15k
Get current play queue (paged, 20 results per page)
"""
queue: list = self.radio_util.active_playlist[0:limit]
start: int = int(data.start)
end: int = start+20
logging.info("queue request with start pos: %s & end pos: %s",
start, end)
queue_full: list = self.radio_util.active_playlist
queue: list = queue_full[start:end]
logging.info("queue length: %s", len(queue))
queue_out: list[dict] = []
for x, item in enumerate(queue):
queue_out.append(
{
"pos": x,
"pos": queue_full.index(item),
"id": item.get("id"),
"uuid": item.get("uuid"),
"artist": item.get("artist"),
@ -146,7 +149,13 @@ class Radio(FastAPI):
"duration": item.get("duration"),
}
)
return JSONResponse(content={"items": queue_out})
out_json = {
"draw": data.draw,
"recordsTotal": len(queue_full),
"recordsFiltered": len(queue_full) if not data.search else len(queue_full), # todo: implement search
"items": queue_out,
}
return JSONResponse(content=out_json)
async def radio_queue_shift(
self, data: ValidRadioQueueShiftRequest, request: Request
@ -230,6 +239,8 @@ class Radio(FastAPI):
)
return Response(content=album_art, media_type="image/png")
except Exception as e:
logging.debug("album_art_handler Exception: %s",
str(e))
traceback.print_exc()
return RedirectResponse(
url="https://codey.lol/images/radio_art_default.jpg", status_code=302
@ -256,7 +267,7 @@ class Radio(FastAPI):
) -> JSONResponse:
"""
Get next track
Track will be removed from the queue in the process.
(Track will be removed from the queue in the process.)
- **key**: API key
- **skipTo**: Optional UUID to skip to
"""