mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-19 07:33:18 +02:00
Start queued jobs in list order, whether pinned or "Any <model>" (#3200)
This commit is contained in:
@@ -3,17 +3,17 @@
|
||||
*
|
||||
* The backend decides this in SQL (`print_scheduler.check_queue`):
|
||||
*
|
||||
* ORDER BY printer_id, target_model,
|
||||
* been_jumped DESC,
|
||||
* ORDER BY been_jumped DESC,
|
||||
* print_time_seconds ASC NULLS LAST,
|
||||
* position
|
||||
* position, id
|
||||
*
|
||||
* with the first two columns acting purely as a grouping — a row carries
|
||||
* either a `printer_id` or a `target_model`, never both — and the rest
|
||||
* deciding who goes first inside that group. Every UI surface that claims to
|
||||
* show queue order has to reproduce it, and each one that reproduced it
|
||||
* privately drifted: the timeline sorted by `position` alone and so ignored
|
||||
* Shortest-Job-First entirely (#3043). One comparator, three callers.
|
||||
* with the first two keys only when Shortest-Job-First is on. It is one order
|
||||
* across the whole queue, not one per printer (#3200): a job pinned to a
|
||||
* printer and an "Any <model>" job both want that printer, and the one higher
|
||||
* in this order gets it. Every UI surface that claims to show queue order has
|
||||
* to reproduce it, and each one that reproduced it privately drifted: the
|
||||
* timeline sorted by `position` alone and so ignored Shortest-Job-First
|
||||
* entirely (#3043).
|
||||
*/
|
||||
|
||||
interface OrderableQueueItem {
|
||||
@@ -22,12 +22,13 @@ interface OrderableQueueItem {
|
||||
been_jumped?: boolean;
|
||||
print_time_seconds?: number | null;
|
||||
position: number;
|
||||
id?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Which dispatch group an item belongs to: a named printer, a printer model,
|
||||
* or neither. Items only compete with others in their own group, so this is
|
||||
* both the timeline's swimlane and the outer sort key of a flat pending list.
|
||||
* Which swimlane an item is drawn in on the timeline: a named printer, a
|
||||
* printer model, or neither. Display only -- lanes do not decide dispatch
|
||||
* order, which is global (#3200).
|
||||
*
|
||||
* Returned as a string rather than a number because the group is a name, not
|
||||
* a magnitude. The flat list used to fold `target_model` down to
|
||||
@@ -41,7 +42,8 @@ export function queueLaneKey(item: OrderableQueueItem): string {
|
||||
}
|
||||
|
||||
/**
|
||||
* Order two items competing for the same printer or model.
|
||||
* Order two pending items the way the scheduler takes them, whichever printer
|
||||
* or model each is queued for.
|
||||
*
|
||||
* @param sjfEnabled the `queue_shortest_first` setting. When off, the
|
||||
* scheduler orders by position alone and so does this.
|
||||
@@ -65,38 +67,6 @@ export function compareQueueOrder(
|
||||
if (aTime !== bTime) return aTime - bTime;
|
||||
}
|
||||
|
||||
return a.position - b.position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Order a flat list that spans several groups -- a pending list rather than a
|
||||
* per-lane one. Groups stay contiguous; within each, the scheduler's own order
|
||||
* applies.
|
||||
*
|
||||
* Groups themselves are ordered for reading, not to mirror the backend: named
|
||||
* printers by id, then model lanes by name, then unassigned. The backend's own
|
||||
* answer here is `ORDER BY printer_id` with a NULL in it, which SQLite sorts
|
||||
* first and PostgreSQL sorts last -- nothing worth reproducing.
|
||||
*/
|
||||
export function compareQueueOrderAcrossLanes(
|
||||
a: OrderableQueueItem,
|
||||
b: OrderableQueueItem,
|
||||
sjfEnabled: boolean,
|
||||
): number {
|
||||
const aLane = queueLaneKey(a);
|
||||
const bLane = queueLaneKey(b);
|
||||
if (aLane !== bLane) {
|
||||
if (a.printer_id != null && b.printer_id != null) return a.printer_id - b.printer_id;
|
||||
const aRank = laneRank(a);
|
||||
const bRank = laneRank(b);
|
||||
if (aRank !== bRank) return aRank - bRank;
|
||||
return aLane < bLane ? -1 : 1;
|
||||
}
|
||||
return compareQueueOrder(a, b, sjfEnabled);
|
||||
}
|
||||
|
||||
function laneRank(item: OrderableQueueItem): number {
|
||||
if (item.printer_id != null) return 0;
|
||||
if (item.target_model) return 1;
|
||||
return 2;
|
||||
if (a.position !== b.position) return a.position - b.position;
|
||||
return (a.id ?? 0) - (b.id ?? 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user