Show the job the scheduler starts next on the printer card (#3200)

This commit is contained in:
maziggy
2026-10-01 13:06:01 +02:00
2 changed files with 35 additions and 1 deletions
+6 -1
View File
@@ -616,7 +616,12 @@ async def list_queue(
# Cross-model candidates (#671) and their files, for the card label.
selectinload(PrintQueueItem.variants).selectinload(PrintQueueVariant.library_file),
)
.order_by(PrintQueueItem.printer_id.nulls_first(), PrintQueueItem.position)
# The order the scheduler dispatches in (#3200), so the first pending
# item for a printer is the one it will start next -- which is what the
# printer card's "Next in queue" shows. Sorting by printer first put
# every "Any <model>" job (no printer_id) ahead of a job pinned to that
# printer, whatever their positions.
.order_by(PrintQueueItem.position, PrintQueueItem.id)
)
if user is not None and not can_read_all:
query = query.where(PrintQueueItem.created_by_id == user.id)
@@ -119,6 +119,35 @@ class TestPrintQueueAPI:
assert response.status_code == 200
assert isinstance(response.json(), list)
@pytest.mark.asyncio
@pytest.mark.integration
@pytest.mark.parametrize("pinned_first", [True, False], ids=["pinned-above-any", "any-above-pinned"])
async def test_list_follows_queue_position_across_pinned_and_any_jobs(
self, async_client: AsyncClient, printer_factory, queue_item_factory, pinned_first
):
"""A printer's first pending item is the one the scheduler starts next (#3200).
The printer card's "Next in queue" shows that first item. The list used
to sort by printer first, which put every "Any <model>" job (no
printer_id) ahead of a job pinned to the printer -- the order the
scheduler itself had until #3200 -- so the card kept naming a lower
"Any" job after dispatch was fixed.
"""
printer = await printer_factory(model="P2S")
pinned_pos, any_pos = (1, 2) if pinned_first else (2, 1)
pinned = await queue_item_factory(printer_id=printer.id, position=pinned_pos)
any_model = await queue_item_factory(printer_id=None, target_model="P2S", position=any_pos)
later_any = await queue_item_factory(printer_id=None, target_model="P2S", position=3)
response = await async_client.get(
"/api/v1/queue/", params={"printer_id": printer.id, "status": "pending", "target_model": "P2S"}
)
assert response.status_code == 200
ids = [item["id"] for item in response.json()]
expected_head = [pinned.id, any_model.id] if pinned_first else [any_model.id, pinned.id]
assert ids == [*expected_head, later_any.id]
@pytest.mark.asyncio
@pytest.mark.integration
async def test_add_to_queue(self, async_client: AsyncClient, printer_factory, archive_factory, db_session):