changed logging concept, reworked task manager
This commit is contained in:
parent
6c7356598a
commit
0b268a7245
19 changed files with 497 additions and 260 deletions
|
@ -2,41 +2,19 @@
|
|||
|
||||
#include "flactomp3.h"
|
||||
|
||||
constexpr const std::array<std::string_view, Loggable::fatal + 1> logSettings({
|
||||
/*debug*/ "\e[90m",
|
||||
/*info*/ "\e[32m",
|
||||
/*minor*/ "\e[34m",
|
||||
/*major*/ "\e[94m",
|
||||
/*warning*/ "\e[33m",
|
||||
/*error*/ "\e[31m",
|
||||
/*fatal*/ "\e[91m"
|
||||
});
|
||||
|
||||
constexpr const std::array<std::string_view, Loggable::fatal + 1> logHeaders({
|
||||
/*debug*/ "DEBUG: ",
|
||||
/*info*/ "INFO: ",
|
||||
/*minor*/ "MINOR: ",
|
||||
/*major*/ "MAJOR: ",
|
||||
/*warning*/ "WARNING: ",
|
||||
/*error*/ "ERROR: ",
|
||||
/*fatal*/ "FATAL: "
|
||||
});
|
||||
|
||||
TaskManager::TaskManager(const std::shared_ptr<Settings>& settings):
|
||||
TaskManager::TaskManager(const std::shared_ptr<Settings>& settings, const std::shared_ptr<Printer>& logger):
|
||||
settings(settings),
|
||||
logger(logger),
|
||||
busyThreads(0),
|
||||
maxTasks(0),
|
||||
completeTasks(0),
|
||||
terminate(false),
|
||||
printMutex(),
|
||||
running(false),
|
||||
queueMutex(),
|
||||
busyMutex(),
|
||||
loopConditional(),
|
||||
waitConditional(),
|
||||
threads(),
|
||||
jobs(),
|
||||
boundLoopCondition(std::bind(&TaskManager::loopCondition, this)),
|
||||
boundWaitCondition(std::bind(&TaskManager::waitCondition, this))
|
||||
jobs()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -44,126 +22,107 @@ TaskManager::~TaskManager() {
|
|||
}
|
||||
|
||||
void TaskManager::queueJob(const std::filesystem::path& source, const std::filesystem::path& destination) {
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(queueMutex);
|
||||
jobs.emplace(source, destination);
|
||||
}
|
||||
std::unique_lock<std::mutex> lock(queueMutex);
|
||||
jobs.emplace(source, destination);
|
||||
|
||||
++maxTasks;
|
||||
logger->setStatusMessage(std::to_string(completeTasks) + "/" + std::to_string(maxTasks));
|
||||
|
||||
lock.unlock();
|
||||
loopConditional.notify_one();
|
||||
waitConditional.notify_all();
|
||||
}
|
||||
|
||||
bool TaskManager::busy() const {
|
||||
bool result;
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(queueMutex);
|
||||
result = !jobs.empty();
|
||||
}
|
||||
|
||||
return result;
|
||||
std::lock_guard lock(queueMutex);
|
||||
return !jobs.empty();
|
||||
}
|
||||
|
||||
void TaskManager::start() {
|
||||
std::lock_guard lock(queueMutex);
|
||||
if (running)
|
||||
return;
|
||||
|
||||
const uint32_t num_threads = std::thread::hardware_concurrency();
|
||||
for (uint32_t ii = 0; ii < num_threads; ++ii)
|
||||
threads.emplace_back(std::thread(&TaskManager::loop, this));
|
||||
|
||||
running = true;
|
||||
}
|
||||
|
||||
void TaskManager::loop() {
|
||||
while (true) {
|
||||
std::pair<std::string, std::string> pair;
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(queueMutex);
|
||||
loopConditional.wait(lock, boundLoopCondition);
|
||||
if (terminate)
|
||||
return;
|
||||
std::unique_lock<std::mutex> lock(queueMutex);
|
||||
while (!terminate && jobs.empty())
|
||||
loopConditional.wait(lock);
|
||||
|
||||
pair = jobs.front();
|
||||
++busyThreads;
|
||||
waitConditional.notify_all();
|
||||
jobs.pop();
|
||||
}
|
||||
if (terminate)
|
||||
return;
|
||||
|
||||
std::pair<std::string, std::string> pair = jobs.front();
|
||||
++busyThreads;
|
||||
jobs.pop();
|
||||
lock.unlock();
|
||||
|
||||
JobResult result;
|
||||
switch (settings->getType()) {
|
||||
case Settings::mp3:
|
||||
result = mp3Job(pair.first, pair.second + ".mp3");
|
||||
result = mp3Job(pair.first, pair.second + ".mp3", settings->getLogLevel());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
lock.lock();
|
||||
++completeTasks;
|
||||
printProgress(result, pair.first, pair.second);
|
||||
logger->printNested(
|
||||
result.first ? "Encoding complete but there are messages about it" : "Encoding failed!",
|
||||
{"Source: \t" + pair.first, "Destination: \t" + pair.second},
|
||||
result.second,
|
||||
std::to_string(completeTasks) + "/" + std::to_string(maxTasks)
|
||||
);
|
||||
--busyThreads;
|
||||
lock.unlock();
|
||||
waitConditional.notify_all();
|
||||
}
|
||||
}
|
||||
|
||||
bool TaskManager::loopCondition() const {
|
||||
return !jobs.empty() || terminate;
|
||||
}
|
||||
|
||||
bool TaskManager::waitCondition() const {
|
||||
return busyThreads == 0 && !busy();
|
||||
}
|
||||
|
||||
void TaskManager::stop() {
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(queueMutex);
|
||||
terminate = true;
|
||||
}
|
||||
std::unique_lock lock(queueMutex);
|
||||
if (!running)
|
||||
return;
|
||||
|
||||
terminate = true;
|
||||
|
||||
lock.unlock();
|
||||
loopConditional.notify_all();
|
||||
for (std::thread& thread : threads)
|
||||
thread.join();
|
||||
|
||||
lock.lock();
|
||||
threads.clear();
|
||||
running = false;
|
||||
logger->clearStatusMessage();
|
||||
}
|
||||
|
||||
void TaskManager::wait() {
|
||||
std::unique_lock<std::mutex> lock(busyMutex);
|
||||
waitConditional.wait(lock, boundWaitCondition);
|
||||
std::unique_lock lock(queueMutex);
|
||||
while (busyThreads != 0 || !jobs.empty())
|
||||
waitConditional.wait(lock);
|
||||
}
|
||||
|
||||
TaskManager::JobResult TaskManager::mp3Job(const std::filesystem::path& source, const std::filesystem::path& destination) {
|
||||
FLACtoMP3 convertor(Loggable::debug);
|
||||
unsigned int TaskManager::getCompleteTasks() const {
|
||||
std::lock_guard lock(queueMutex);
|
||||
return completeTasks;
|
||||
}
|
||||
|
||||
TaskManager::JobResult TaskManager::mp3Job(
|
||||
const std::filesystem::path& source,
|
||||
const std::filesystem::path& destination,
|
||||
Logger::Severity logLevel)
|
||||
{
|
||||
FLACtoMP3 convertor(logLevel);
|
||||
convertor.setInputFile(source);
|
||||
convertor.setOutputFile(destination);
|
||||
bool result = convertor.run();
|
||||
return {result, convertor.getHistory()};
|
||||
}
|
||||
|
||||
void TaskManager::printProgress() const {
|
||||
std::unique_lock<std::mutex> lock(printMutex);
|
||||
std::cout << "\r" << completeTasks << "/" << maxTasks << std::flush;
|
||||
}
|
||||
|
||||
void TaskManager::printProgress(
|
||||
const TaskManager::JobResult& result,
|
||||
const std::filesystem::path& source,
|
||||
const std::filesystem::path& destination) const
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(printMutex);
|
||||
if (result.first) {
|
||||
if (result.second.size() > 0) {
|
||||
std::cout << "\r\e[1m" << "Encoding complete but there are messages about it" << "\e[0m" << std::endl;
|
||||
printLog(result, source, destination);
|
||||
}
|
||||
} else {
|
||||
std::cout << "\r\e[1m" << "Encoding failed!" << "\e[0m" << std::endl;
|
||||
printLog(result, source, destination);
|
||||
}
|
||||
std::cout << "\r" << completeTasks << "/" << maxTasks << std::flush;
|
||||
}
|
||||
|
||||
void TaskManager::printLog(
|
||||
const TaskManager::JobResult& result,
|
||||
const std::filesystem::path& source,
|
||||
const std::filesystem::path& destination)
|
||||
{
|
||||
std::cout << "Source: \t" << source << std::endl;
|
||||
std::cout << "Destination: \t" << destination << std::endl;
|
||||
for (const Loggable::Message& msg : result.second) {
|
||||
std::cout << "\t" << logSettings[msg.first] << "\e[1m" << logHeaders[msg.first] << "\e[22m" << msg.second << std::endl;
|
||||
}
|
||||
std::cout << "\e[0m" << std::endl;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue