bool CAdvThread::appendRunnableTask(runnable_closure run, int run_type) { if((run_type == eRunnableType::LONG_TASK || run_type == eRunnableType::LONG_TASK_EXTRA) && currentRunnableClosure) return false; if(run_type == eRunnableType::LONG_TASK_EXTRA) qDebug() << "LONG_TASK_EXTRA append to thread's queue"; std::unique_lock<std::mutex> locker(threadMutex); taskArray.push(run); conditionVariable.notify_one(); auto currentTime = std::chrono::high_resolution_clock::now(); auto delta = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - lastTimeOfTaskQuantityAnalize).count(); if(delta >= 1000) { lastTimeOfTaskQuantityAnalize = currentTime; if(run_type == eRunnableType::SHORT_TASK || run_type == eRunnableType::REPEAT_TASK) { CAdvThreadPool::getInstance().getEmitter()->sendSignal_MeanCountTasks(getThreadNumber(), QString("%1/%2").arg(averageTaskQuantity).arg(taskArray.size())); } averageTaskQuantity = 0; } averageTaskQuantity++; return true; }
MergeListElement::MergeListElement(const std::string & database, const std::string & table, const FutureMergedMutatedPart & future_part) : database{database}, table{table}, partition_id{future_part.part_info.partition_id} , result_part_name{future_part.name} , result_data_version{future_part.part_info.getDataVersion()} , num_parts{future_part.parts.size()} , thread_number{getThreadNumber()} { for (const auto & source_part : future_part.parts) { source_part_names.emplace_back(source_part->name); std::shared_lock<std::shared_mutex> part_lock(source_part->columns_lock); total_size_bytes_compressed += source_part->bytes_on_disk; total_size_marks += source_part->getMarksCount(); total_rows_count += source_part->index_granularity.getTotalRows(); } if (!future_part.parts.empty()) { source_data_version = future_part.parts[0]->info.getDataVersion(); is_mutation = (result_data_version != source_data_version); } /// Each merge is executed into separate background processing pool thread background_thread_memory_tracker = CurrentThread::getMemoryTracker(); if (background_thread_memory_tracker) { memory_tracker.setMetric(CurrentMetrics::MemoryTrackingForMerges); background_thread_memory_tracker_prev_parent = background_thread_memory_tracker->getParent(); background_thread_memory_tracker->setParent(&memory_tracker); } }
void CAdvThread::threadMainFunction() { getCurrentHandle(); setAffinity(); while (isThreadWork) { std::unique_lock<std::mutex> locker(threadMutex); // wait notification and check that it does not a false awakening // Thread must awake if list is not empty or it was poweroff conditionVariable.wait(locker, [&](){ return !taskArray.empty() || !isThreadWork || affinityData.coreChanged;}); while(!taskArray.empty()) { if(!isThreadWork)//if stop thread of pool { while(!taskArray.empty())//stop all tasks { runnable_closure runClosure = taskArray.front();//get task from array taskArray.pop(); locker.unlock();//unlock before task call runClosure(int(eRUN_MODES::STOP), 0); locker.lock(); } return; } currentRunnableClosure = taskArray.front();//get task from array taskArray.pop(); locker.unlock();//unlock before task call try { if(threadType == eThreadType::THREAD_SHARED && getRunType() == eRunnableType::SHORT_TASK) { QString stringTimerResult = currentRunnableClosure(int(eRUN_MODES::IS_TIMER_OVER), 0); if(stringTimerResult == QString("1")) { lastTimeOfTaskLaunch = std::chrono::high_resolution_clock::now(); isReadyForSend_WarningAboutShortTaskFreeze = true; currentRunnableClosure(int(eRUN_MODES::RUN), 0); isReadyForSend_WarningAboutShortTaskFreeze = false; } else //task hold over appendRunnableTask(currentRunnableClosure, eRunnableType::SHORT_TASK); } else { lastTimeOfTaskLaunch = std::chrono::high_resolution_clock::now(); isReadyForSend_WarningAboutShortTaskFreeze = true; currentRunnableClosure(int(eRUN_MODES::RUN), 0); isReadyForSend_WarningAboutShortTaskFreeze = false; } } catch(holdOverTask_Exception action) { if(threadType == eThreadType::THREAD_SHARED && getRunType() == eRunnableType::SHORT_TASK) { int counterOfExecution = currentRunnableClosure(int(eRUN_MODES::GET_COUNTER), 0).toInt(); if(counterOfExecution>0) { CAdvThreadPool::getInstance().getEmitter()->addWarningToShell(QString("Task was hold over - counter = %1 (%2)").arg(counterOfExecution) .arg(QString::fromStdString(action.what())), eLogWarning::message); currentRunnableClosure(int(eRUN_MODES::DECREASE_COUNTER), 0); currentRunnableClosure(int(eRUN_MODES::START_TIMER_FOR_INTERVAL), action.getInterval()); appendRunnableTask(currentRunnableClosure, eRunnableType::SHORT_TASK); } else { CAdvThreadPool::getInstance().getEmitter()->addWarningToShell(QString("Task will not processing - counter over (%2)").arg(counterOfExecution) .arg(QString::fromStdString(action.what())), eLogWarning::warning); } } } catch(std::exception& e) { QString temp = QString("%1 - CAdvThread::threadMainFunction - ").arg(e.what()); temp += getWho(); std::cout<<temp.toStdString()<<std::endl; CAdvThreadPool::getInstance().getEmitter()->addWarningToShell(temp, eLogWarning::warning); } catch(...) { QString temp = QString("Undefined exception - CAdvThread::threadMainFunction - "); temp += getWho(); std::cout<<temp.toStdString()<<std::endl; CAdvThreadPool::getInstance().getEmitter()->addWarningToShell(temp, eLogWarning::warning); } locker.lock(); // lock before m_TaskArray.empty() currentRunnableClosure = nullptr; if(threadType == eThreadType::THREAD_NOT_SHARED) CAdvThreadPool::getInstance().getEmitter()->sendSignal_DeleteLongTask(getThreadNumber()); else if(threadType == eThreadType::THREAD_NOT_SHARED_EXTRA) CAdvThreadPool::getInstance().getEmitter()->sendSignal_DeleteExtraLongTask(getThreadNumber()); } } }