stabilized app

This commit is contained in:
Torsten Schulz
2025-07-21 14:59:43 +02:00
committed by Torsten (PC)
parent 51fd9fcd13
commit 1451225978
25 changed files with 3590 additions and 228 deletions

224
src/politics_worker.cpp Normal file
View File

@@ -0,0 +1,224 @@
// File: politics_worker.cpp
#include "politics_worker.h"
#include <iostream>
#include <chrono>
PoliticsWorker::PoliticsWorker(ConnectionPool &pool, MessageBroker &broker)
: Worker(pool, broker, "PoliticsWorker")
{
}
PoliticsWorker::~PoliticsWorker()
{
}
void PoliticsWorker::run() {
auto lastExecutionDate = std::chrono::system_clock::time_point{};
while (runningWorker) {
signalActivity();
auto now = std::chrono::system_clock::now();
auto todayFloor = std::chrono::floor<std::chrono::days>(now);
auto targetTime = todayFloor + std::chrono::hours(3); // 03:00 Uhr
if (now >= targetTime && lastExecutionDate < todayFloor) {
signalActivity();
performDailyPoliticsTask();
lastExecutionDate = todayFloor;
}
for (int i = 0; i < 5 && runningWorker.load(); ++i) {
signalActivity();
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
}
void PoliticsWorker::performDailyPoliticsTask() {
try {
// … (Schritte für Notifications und evaluatePoliticalPositions) …
// 3) Elections anlegen und **je 2 × posts_to_fill** Kandidaten hinzufügen
{
setCurrentStep("Schedule Elections and Insert Candidates");
// 3a) Neue Elections erzeugen (liefert jetzt auch posts_to_fill)
auto elections = scheduleElections();
if (!elections.empty()) {
for (auto const & tpl : elections) {
int electionId = std::get<0>(tpl);
int regionId = std::get<1>(tpl);
int postsToFill = std::get<2>(tpl);
ConnectionGuard connGuard(pool);
auto &db = connGuard.get();
db.prepare("INSERT_CANDIDATES", QUERY_INSERT_CANDIDATES);
// $1 = electionId, $2 = regionId, $3 = postsToFill
db.execute("INSERT_CANDIDATES", {
std::to_string(electionId),
std::to_string(regionId),
std::to_string(postsToFill)
});
}
}
}
// … nach scheduleElections() & Kandidaten …
{
setCurrentStep("Process Elections After 3 Days");
auto newOffices = processElections();
for (auto const &tup : newOffices) {
notifyOfficeFilled({tup});
}
}
} catch (std::exception const & e) {
std::cerr << "[PoliticsWorker] Fehler bei performDailyPoliticsTask: " << e.what() << "\n";
}
}
void PoliticsWorker::evaluatePoliticalPositions(
std::unordered_map<int,int>& requiredPerRegion,
std::unordered_map<int,int>& occupiedPerRegion
) {
ConnectionGuard connGuard(pool);
auto &db = connGuard.get();
signalActivity();
db.prepare("COUNT_OFFICES_PER_REGION", QUERY_COUNT_OFFICES_PER_REGION);
signalActivity();
const auto result = db.execute("COUNT_OFFICES_PER_REGION");
signalActivity();
for (const auto &row : result) {
int regionId = std::stoi(row.at("region_id"));
int reqCount = std::stoi(row.at("required_count"));
int occCount = std::stoi(row.at("occupied_count"));
requiredPerRegion[regionId] = reqCount;
occupiedPerRegion[regionId] = occCount;
signalActivity();
}
}
// politics_worker.cpp (Auszug)
std::vector<std::tuple<int,int,int>> PoliticsWorker::scheduleElections() {
ConnectionGuard connGuard(pool);
auto &db = connGuard.get();
signalActivity();
db.prepare("SELECT_NEEDED_ELECTIONS", QUERY_SELECT_NEEDED_ELECTIONS);
signalActivity();
auto result = db.execute("SELECT_NEEDED_ELECTIONS");
signalActivity();
std::vector<std::tuple<int,int,int>> created;
created.reserve(result.size());
for (auto const & row : result) {
int electionId = std::stoi(row.at("election_id"));
int regionId = std::stoi(row.at("region_id"));
int postsToFill = std::stoi(row.at("posts_to_fill"));
created.emplace_back(electionId, regionId, postsToFill);
signalActivity();
}
return created;
}
std::vector<std::tuple<int,int,int,int>> PoliticsWorker::processExpiredOfficesAndFill() {
ConnectionGuard connGuard(pool);
auto &db = connGuard.get();
signalActivity();
db.prepare("PROCESS_EXPIRED_AND_FILL", QUERY_PROCESS_EXPIRED_AND_FILL);
signalActivity();
const auto result = db.execute("PROCESS_EXPIRED_AND_FILL");
signalActivity();
std::vector<std::tuple<int,int,int,int>> created;
for (const auto &row : result) {
int officeId = std::stoi(row.at("office_id"));
int officeTypeId = std::stoi(row.at("office_type_id"));
int characterId = std::stoi(row.at("character_id"));
int regionId = std::stoi(row.at("region_id"));
created.emplace_back(officeId, officeTypeId, characterId, regionId);
signalActivity();
}
return created;
}
std::vector<int> PoliticsWorker::getUserIdsInCitiesOfRegions(const std::vector<int>& regionIds) {
if (regionIds.empty()) {
return {};
}
ConnectionGuard connGuard(pool);
auto &db = connGuard.get();
std::vector<int> userIds;
for (int rid : regionIds) {
signalActivity();
db.prepare("GET_USERS_IN_CITIES", QUERY_USERS_IN_CITIES_OF_REGIONS);
signalActivity();
const auto rows = db.execute("GET_USERS_IN_CITIES", { std::to_string(rid) });
signalActivity();
for (const auto &row : rows) {
int uid = std::stoi(row.at("user_id"));
userIds.push_back(uid);
signalActivity();
}
}
return userIds;
}
void PoliticsWorker::notifyOfficeExpirations() {
ConnectionGuard connGuard(pool);
auto &db = connGuard.get();
signalActivity();
db.prepare("NOTIFY_OFFICE_EXPIRATION", QUERY_NOTIFY_OFFICE_EXPIRATION);
signalActivity();
db.execute("NOTIFY_OFFICE_EXPIRATION");
signalActivity();
}
void PoliticsWorker::notifyElectionCreated(const std::vector<std::pair<int,int>>& elections) {
ConnectionGuard connGuard(pool);
auto &db = connGuard.get();
db.prepare("NOTIFY_ELECTION_CREATED", QUERY_NOTIFY_ELECTION_CREATED);
for (const auto &pr : elections) {
signalActivity();
db.execute("NOTIFY_ELECTION_CREATED", { std::to_string(pr.first) });
signalActivity();
}
}
void PoliticsWorker::notifyOfficeFilled(const std::vector<std::tuple<int,int,int,int>>& newOffices) {
ConnectionGuard connGuard(pool);
auto &db = connGuard.get();
db.prepare("NOTIFY_OFFICE_FILLED", QUERY_NOTIFY_OFFICE_FILLED);
for (const auto &tup : newOffices) {
int characterId = std::get<2>(tup);
signalActivity();
db.execute("NOTIFY_OFFICE_FILLED", { std::to_string(characterId) });
signalActivity();
}
}
std::vector<std::tuple<int,int,int,int>> PoliticsWorker::processElections() {
ConnectionGuard connGuard(pool);
auto &db = connGuard.get();
db.prepare("PROCESS_ELECTIONS", QUERY_PROCESS_ELECTIONS);
auto result = db.execute("PROCESS_ELECTIONS", {});
std::vector<std::tuple<int,int,int,int>> created;
for (auto const &row : result) {
int officeId = std::stoi(row.at("office_id"));
int officeTypeId = std::stoi(row.at("office_type_id"));
int characterId = std::stoi(row.at("character_id"));
int regionId = std::stoi(row.at("region_id"));
created.emplace_back(officeId, officeTypeId, characterId, regionId);
}
return created;
}