Enhance production job handling in DirectorWorker: Implemented a limit on the number of concurrent production jobs per branch to a maximum of two. Updated SQL query for fetching finished productions to aggregate quality ratings correctly and ensure unique results per production ID. Improved comments for clarity on the logic and SQL structure.
This commit is contained in:
@@ -460,6 +460,7 @@ impl DirectorWorker {
|
|||||||
plan: &ProductionPlan,
|
plan: &ProductionPlan,
|
||||||
) -> Result<(), DbError> {
|
) -> Result<(), DbError> {
|
||||||
let running = plan.running_productions;
|
let running = plan.running_productions;
|
||||||
|
// Maximal zwei parallele Produktionen pro Branch zulassen.
|
||||||
if running >= 2 {
|
if running >= 2 {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"[DirectorWorker] Bereits zu viele laufende Produktionen ({}), keine neue Produktion.",
|
"[DirectorWorker] Bereits zu viele laufende Produktionen ({}), keine neue Produktion.",
|
||||||
@@ -530,16 +531,23 @@ impl DirectorWorker {
|
|||||||
|
|
||||||
conn.prepare("insert_production", QUERY_INSERT_PRODUCTION)?;
|
conn.prepare("insert_production", QUERY_INSERT_PRODUCTION)?;
|
||||||
|
|
||||||
let mut remaining = to_produce;
|
// Anzahl neuer Produktions-Jobs so begrenzen, dass zusammen mit den
|
||||||
|
// bereits laufenden maximal 2 parallele Produktionen pro Branch aktiv
|
||||||
|
// sind. Jeder Job wird in Batches von max. 100 Stück aufgeteilt.
|
||||||
|
let mut remaining_qty = to_produce;
|
||||||
let mut inserted_total = 0;
|
let mut inserted_total = 0;
|
||||||
while remaining > 0 {
|
let mut started_jobs = 0;
|
||||||
let batch = remaining.min(100);
|
let max_new_jobs = (2 - running).max(0);
|
||||||
|
|
||||||
|
while remaining_qty > 0 && started_jobs < max_new_jobs {
|
||||||
|
let batch = remaining_qty.min(100);
|
||||||
conn.execute(
|
conn.execute(
|
||||||
"insert_production",
|
"insert_production",
|
||||||
&[&plan.branch_id, &plan.product_id, &batch],
|
&[&plan.branch_id, &plan.product_id, &batch],
|
||||||
)?;
|
)?;
|
||||||
remaining -= batch;
|
remaining_qty -= batch;
|
||||||
inserted_total += batch;
|
inserted_total += batch;
|
||||||
|
started_jobs += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
eprintln!(
|
eprintln!(
|
||||||
|
|||||||
@@ -29,33 +29,55 @@ struct StockInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SQL-Queries analog zur C++-Implementierung
|
// SQL-Queries analog zur C++-Implementierung
|
||||||
|
// Wichtig: Pro `production.id` darf hier **genau eine Zeile** zurückkommen.
|
||||||
|
// Durch die Joins auf Director/Knowledge kann es sonst zu Mehrfachzeilen mit
|
||||||
|
// unterschiedlicher berechneter Qualität kommen. Deshalb wird die Qualität
|
||||||
|
// über MAX() aggregiert und nach `production_id` gruppiert.
|
||||||
const QUERY_GET_FINISHED_PRODUCTIONS: &str = r#"
|
const QUERY_GET_FINISHED_PRODUCTIONS: &str = r#"
|
||||||
SELECT DISTINCT
|
SELECT
|
||||||
p.id AS production_id,
|
p.id AS production_id,
|
||||||
p.branch_id,
|
p.branch_id,
|
||||||
p.product_id,
|
p.product_id,
|
||||||
p.quantity,
|
p.quantity,
|
||||||
p.start_timestamp,
|
p.start_timestamp,
|
||||||
pr.production_time,
|
pr.production_time,
|
||||||
k.character_id,
|
-- Aggregierte Qualitätsbewertung pro Produktion
|
||||||
|
MAX(
|
||||||
CASE
|
CASE
|
||||||
WHEN k2.id IS NOT NULL
|
WHEN k2.id IS NOT NULL
|
||||||
THEN (k.knowledge * 2 + k2.knowledge) / 3
|
THEN (k.knowledge * 2 + k2.knowledge) / 3
|
||||||
ELSE k.knowledge
|
ELSE k.knowledge
|
||||||
END AS quality,
|
END
|
||||||
|
) AS quality,
|
||||||
br.region_id,
|
br.region_id,
|
||||||
br.falukant_user_id AS user_id
|
br.falukant_user_id AS user_id
|
||||||
FROM falukant_data.production p
|
FROM falukant_data.production p
|
||||||
JOIN falukant_type.product pr ON p.product_id = pr.id
|
JOIN falukant_type.product pr
|
||||||
JOIN falukant_data.branch br ON p.branch_id = br.id
|
ON p.product_id = pr.id
|
||||||
JOIN falukant_data.character c ON c.user_id = br.falukant_user_id
|
JOIN falukant_data.branch br
|
||||||
JOIN falukant_data.knowledge k ON p.product_id = k.product_id AND k.character_id = c.id
|
ON p.branch_id = br.id
|
||||||
JOIN falukant_data.stock s ON s.branch_id = br.id
|
JOIN falukant_data.character c
|
||||||
LEFT JOIN falukant_data.director d ON d.employer_user_id = c.user_id
|
ON c.user_id = br.falukant_user_id
|
||||||
|
JOIN falukant_data.knowledge k
|
||||||
|
ON p.product_id = k.product_id
|
||||||
|
AND k.character_id = c.id
|
||||||
|
JOIN falukant_data.stock s
|
||||||
|
ON s.branch_id = br.id
|
||||||
|
LEFT JOIN falukant_data.director d
|
||||||
|
ON d.employer_user_id = c.user_id
|
||||||
LEFT JOIN falukant_data.knowledge k2
|
LEFT JOIN falukant_data.knowledge k2
|
||||||
ON k2.character_id = d.director_character_id
|
ON k2.character_id = d.director_character_id
|
||||||
AND k2.product_id = p.product_id
|
AND k2.product_id = p.product_id
|
||||||
WHERE p.start_timestamp + INTERVAL '1 minute' * pr.production_time <= NOW()
|
WHERE p.start_timestamp + INTERVAL '1 minute' * pr.production_time <= NOW()
|
||||||
|
GROUP BY
|
||||||
|
p.id,
|
||||||
|
p.branch_id,
|
||||||
|
p.product_id,
|
||||||
|
p.quantity,
|
||||||
|
p.start_timestamp,
|
||||||
|
pr.production_time,
|
||||||
|
br.region_id,
|
||||||
|
br.falukant_user_id
|
||||||
ORDER BY p.start_timestamp;
|
ORDER BY p.start_timestamp;
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user