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;
}
示例#2
0
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());
        }
    }
}