Пример #1
0
void CSSHScheduler::makeScheduleImpl(const CTopology& _topology,
                                     const CAgentChannel::weakConnectionPtrVector_t& _channels)
{
    m_schedule.clear();

    size_t nofChannels = _channels.size();
    // Fill host name to channel index map in order to reduce number of regex matches and speed up scheduling.
    map<string, vector<size_t>> hostToChannelMap;
    for (size_t iChannel = 0; iChannel < nofChannels; ++iChannel)
    {
        const auto& v = _channels[iChannel];
        if (v.expired())
            continue;
        auto ptr = v.lock();
        const SHostInfoCmd& hostInfo = ptr->getRemoteHostInfo();
        hostToChannelMap[hostInfo.m_host].push_back(iChannel);
    }

    // TODO: before scheduling the collections we have to sort them by a number of tasks in the collection.
    // TODO: for the moment we are not able to schedule collection without requirements.

    // Collect all tasks that belong to collections
    set<uint64_t> tasksInCollections;
    CollectionMap_t collectionMap;
    CTopology::TaskCollectionIteratorPair_t collections = _topology.getTaskCollectionIterator();
    for (auto it = collections.first; it != collections.second; it++)
    {
        const vector<uint64_t>& taskHashes = _topology.getTaskHashesByTaskCollectionHash(it->first);
        tasksInCollections.insert(taskHashes.begin(), taskHashes.end());
        collectionMap[it->second->getNofTasks()].push_back(it->first);
    }

    set<uint64_t> scheduledTasks;

    scheduleCollections(_topology, _channels, hostToChannelMap, scheduledTasks, collectionMap, true);
    scheduleTasks(_topology, _channels, hostToChannelMap, scheduledTasks, tasksInCollections, true);
    scheduleCollections(_topology, _channels, hostToChannelMap, scheduledTasks, collectionMap, false);
    scheduleTasks(_topology, _channels, hostToChannelMap, scheduledTasks, tasksInCollections, false);

    size_t totalNofTasks = _topology.getMainGroup()->getTotalNofTasks();
    if (totalNofTasks != m_schedule.size())
    {
        printSchedule();
        stringstream ss;
        ss << "Unable to make a schedule for tasks. Number of requested tasks: " << totalNofTasks
           << ". Number of scheduled tasks: " << m_schedule.size();
        throw runtime_error(ss.str());
    }

    printSchedule();
}
Пример #2
0
void CSSHScheduler::scheduleCollections(const CTopology& _topology,
                                        const CAgentChannel::weakConnectionPtrVector_t& _channels,
                                        map<string, vector<size_t>>& _hostToChannelMap,
                                        set<uint64_t>& _scheduledTasks,
                                        const CollectionMap_t& _collectionMap,
                                        bool useRequirement)
{
    for (const auto& it_col : _collectionMap)
    {
        for (auto id : it_col.second)
        {
            TaskCollectionPtr_t collection = _topology.getTaskCollectionByHash(id);

            // First path only for collections with requirements;
            // Second path for collections without requirements.
            if ((useRequirement && collection->getRequirement() == nullptr) ||
                (!useRequirement && collection->getRequirement() != nullptr))
                continue;

            bool collectionAssigned = false;

            for (auto& v : _hostToChannelMap)
            {
                if (v.second.size() >= collection->getNofTasks() &&
                    (!useRequirement || (useRequirement && collection->getRequirement()->hostPatterMatches(v.first))))
                {
                    const vector<uint64_t>& taskHashes = _topology.getTaskHashesByTaskCollectionHash(id);
                    for (auto hash : taskHashes)
                    {
                        const STaskInfo& info = _topology.getTaskInfoByHash(hash);

                        size_t channelIndex = v.second.back();
                        const auto& channel = _channels[channelIndex];

                        SSchedule schedule;
                        schedule.m_channel = channel;
                        schedule.m_task = info.m_task;
                        schedule.m_taskID = hash;
                        schedule.m_taskIndex = info.m_taskIndex;
                        schedule.m_collectionIndex = info.m_collectionIndex;
                        m_schedule.push_back(schedule);

                        v.second.pop_back();

                        _scheduledTasks.insert(hash);
                    }
                    collectionAssigned = true;
                    break;
                }
            }

            if (!collectionAssigned)
            {
                printSchedule();
                stringstream ss;
                ss << "Unable to schedule collection <" << id << "> with path " << collection->getPath();
                throw runtime_error(ss.str());
            }
        }
    }
}