refactor: wait on db flush before returning in API history clear response
This commit is contained in:
parent
6eaa15b37a
commit
03cabe6c70
3 changed files with 36 additions and 1 deletions
|
|
@ -300,6 +300,7 @@ class DownloadQueue(metaclass=Singleton):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
status: dict[str, str] = {}
|
status: dict[str, str] = {}
|
||||||
|
deleted_ids: list[str] = []
|
||||||
|
|
||||||
for id in ids:
|
for id in ids:
|
||||||
try:
|
try:
|
||||||
|
|
@ -349,6 +350,7 @@ class DownloadQueue(metaclass=Singleton):
|
||||||
LOG.error(f"Unable to remove '{itemRef}' local file '{filename}'. {e!s}")
|
LOG.error(f"Unable to remove '{itemRef}' local file '{filename}'. {e!s}")
|
||||||
|
|
||||||
await self.done.delete(id)
|
await self.done.delete(id)
|
||||||
|
deleted_ids.append(id)
|
||||||
|
|
||||||
_status: str = "Removed" if removed_files > 0 else "Cleared"
|
_status: str = "Removed" if removed_files > 0 else "Cleared"
|
||||||
self._notify.emit(
|
self._notify.emit(
|
||||||
|
|
@ -365,6 +367,9 @@ class DownloadQueue(metaclass=Singleton):
|
||||||
LOG.info(msg=msg)
|
LOG.info(msg=msg)
|
||||||
status[id] = "ok"
|
status[id] = "ok"
|
||||||
|
|
||||||
|
if deleted_ids:
|
||||||
|
await self.done._connection.flush()
|
||||||
|
|
||||||
return status
|
return status
|
||||||
|
|
||||||
async def get(self, mode: str = "all") -> dict[str, list[dict[str, ItemDTO]]]:
|
async def get(self, mode: str = "all") -> dict[str, list[dict[str, ItemDTO]]]:
|
||||||
|
|
|
||||||
|
|
@ -215,7 +215,11 @@ async def items_delete(request: Request, queue: DownloadQueue, encoder: Encoder)
|
||||||
page += 1
|
page += 1
|
||||||
|
|
||||||
if not items_to_delete:
|
if not items_to_delete:
|
||||||
return web.json_response(data={"error": "No items matched the filter."}, status=web.HTTPBadRequest.status_code)
|
return web.json_response(
|
||||||
|
data={"items": {}, "deleted": 0},
|
||||||
|
status=web.HTTPOk.status_code,
|
||||||
|
dumps=encoder.encode,
|
||||||
|
)
|
||||||
|
|
||||||
return web.json_response(
|
return web.json_response(
|
||||||
data={
|
data={
|
||||||
|
|
|
||||||
|
|
@ -1336,6 +1336,32 @@ class TestQueueManager:
|
||||||
item.close.assert_awaited_once()
|
item.close.assert_awaited_once()
|
||||||
assert status[item.info._id] == "ok", "Regular running cancel should still report success"
|
assert status[item.info._id] == "ok", "Regular running cancel should still report success"
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_clear_flushes_history_deletes_before_returning(self) -> None:
|
||||||
|
queue_manager = object.__new__(DownloadQueue)
|
||||||
|
queue_manager.config = Mock(remove_files=False, download_path="/tmp")
|
||||||
|
queue_manager._notify = Mock()
|
||||||
|
|
||||||
|
item = Mock()
|
||||||
|
item.info = make_item(id="done-id", title="Finished clip")
|
||||||
|
item.info._id = "done-id"
|
||||||
|
item.info.status = "finished"
|
||||||
|
item.info.filename = "clip.mp4"
|
||||||
|
item.info.folder = ""
|
||||||
|
|
||||||
|
done_store = Mock()
|
||||||
|
done_store.get = AsyncMock(return_value=item)
|
||||||
|
done_store.delete = AsyncMock()
|
||||||
|
done_store._connection = Mock()
|
||||||
|
done_store._connection.flush = AsyncMock()
|
||||||
|
queue_manager.done = done_store
|
||||||
|
|
||||||
|
status = await DownloadQueue.clear(queue_manager, [item.info._id], remove_file=False)
|
||||||
|
|
||||||
|
done_store.delete.assert_awaited_once_with(item.info._id)
|
||||||
|
done_store._connection.flush.assert_awaited_once()
|
||||||
|
assert status[item.info._id] == "ok", "Clear should still report success after flushing deletes"
|
||||||
|
|
||||||
|
|
||||||
class TestPoolManager:
|
class TestPoolManager:
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue