예제 #1
0
/*!
 * This function refreshes the job list. It queries the server for the required
 * information and then updates the list control.
 *
 * \par Notes on the implementation of RefreshList()
 * For efficiency reasons, after the initial refresh, all refreshes are
 * incremental. Because IPC is the slowest part of the whole program the client
 * only gathers the only the information that is subject to have changed from
 * the server. The list control is also left alone during the process so that
 * it is greyed out for as short a period as possible.
 *
 * \par
 * The list control is also updated incrementally, yet for a completely
 * different reason. Whenever the list control is cleared entirely, it not only
 * takes time to reload the entire list, but it resets the current position of
 * the list in the scroller, so every time the client refreshes the user is
 * looking at the top (and most likely irrelevant) portion of the queue again.
 * 
 * \par
 * Due to the incremental nature of this code, it is rather complicated and
 * should be left alone, unless there is a good reason to change it.
 */
void GamessQFrame::RefreshList()
{
	int *ids = mQueueManager.GetJobIds();
	int num = ids[0];

	wxString name;
	int procs;
	Job::Status status;
	Job *job;

	// update any jobs that are out of date, and remove any jobs that no longer
	// exist on the server
    JobList::compatibility_iterator node = mJobList.GetFirst();
	int i = 1;
	while (node) {
		job = node->GetData();
		if (i <= num && job->GetId() == ids[i]) {
			// update the status
			status = job->GetStatus();
			if (status != Job::STATUS_DONE && status != Job::STATUS_ERROR
					&& status != Job::STATUS_CANCELED) {
				job->SetStatus(mQueueManager.GetStatus(ids[i]));
			}
			node = node->GetNext();
			i++;
		} else {
			JobList::compatibility_iterator nextNode = node->GetNext();
			mJobList.DeleteNode(node);
			node = nextNode;
		}
	}

	// add any new jobs for which we do not yet have local copies
	for (; i <= num; i++) {
		name = mQueueManager.GetName(ids[i]);
		procs = mQueueManager.GetNumProcessors(ids[i]);
		status = mQueueManager.GetStatus(ids[i]);
		job = new Job(ids[i], name, wxT(""), status, procs);
		mJobList.Append(job);
	}

	// update the interface
	jobListCtrl->Hide();

	// update the jobs that are in the control and delete any jobs that no
	// longer exist
	node = mJobList.GetFirst();
	i = 0;
	while (i < jobListCtrl->GetItemCount()) {
		if (node && jobListCtrl->GetItemData(i) == node->GetData()->GetId()) {
			jobListCtrl->SetItem(i, 0, node->GetData()->GetName());
			jobListCtrl->SetItem(i, 2, node->GetData()->GetStatusString());
			node = node->GetNext();
			i++;
		} else {
			jobListCtrl->DeleteItem(i);
		}
	}

	// add new entries to the control for the new jobs
	for (;node; i ++, node = node->GetNext()) {
		Job *job = node->GetData();
		int index = jobListCtrl->InsertItem(i, job->GetName());
		jobListCtrl->SetItemData(index, job->GetId());
		wxString procs;
		procs << job->GetNumProcessors();
		jobListCtrl->SetItem(index, 1, procs);
		jobListCtrl->SetItem(index, 2, job->GetStatusString());
	}
	jobListCtrl->Show();

	delete ids;
	mRefreshTimer->Start(mRefreshFrequency, wxTIMER_ONE_SHOT);
}
예제 #2
0
void GridManager::Update(uint32 diff)
{
    for (auto machine : _machines)
        machine->Update(diff);

    for (auto pMachine : _priorityMachines)
        pMachine->Update(diff);

    if (!_waitingJobs.empty())
    {
        Job* job = _waitingJobs.front();
        if (job->GetPriority() == 0)
        {
            std::vector<Machine*> machineVector; // TODO: Every time a job is added this sorted vector is being rebuilt; change that
            machineVector.reserve(_machines.size());

            // put machines in the map into a vector so we can sort them
            std::transform(_machines.begin(), _machines.end(), std::back_inserter(machineVector),
                [](MachineSet::value_type val) { return val; });

            // sort of load balancing, better machines get assigned jobs first
            std::sort(machineVector.begin(), machineVector.end(), [](Machine* m1, Machine* m2) {
                double score1 = ((m1->GetMaxJobs() - m1->GetNumberOfCurrentJobs()) + m1->GetAvailableDiskSpace() + m1->GetAvailableRAM());
                double score2 = ((m2->GetMaxJobs() - m2->GetNumberOfCurrentJobs()) + m2->GetAvailableDiskSpace() + m2->GetAvailableRAM());

                return score1 > score2;
            });

            for (auto& mach : machineVector)
            {
                if (mach->AddJob(job))
                {
                    sLog(Console)->Log("Job %s added to machine %s", job->GetName().c_str(), mach->GetName().c_str());
                    _waitingJobs.pop();
                }
            }
        }
        else
        {
            std::vector<PriorityMachine*> machineVector; // TODO: Every time a job is added this sorted vector is being rebuilt; change that
            machineVector.reserve(_priorityMachines.size());

            // put machines in the map into a vector so we can sort them
            std::transform(_priorityMachines.begin(), _priorityMachines.end(), std::back_inserter(machineVector),
                [](PriorityMachineSet::value_type val) { return val; });

            // sort of load balancing, better machines get assigned jobs first
            std::sort(machineVector.begin(), machineVector.end(), [](PriorityMachine* m1, PriorityMachine* m2) {
                double score1 = ((m1->GetMaxJobs() - m1->GetNumberOfCurrentJobs()) + m1->GetAvailableDiskSpace() + m1->GetAvailableRAM());
                double score2 = ((m2->GetMaxJobs() - m2->GetNumberOfCurrentJobs()) + m2->GetAvailableDiskSpace() + m2->GetAvailableRAM());

                return score1 > score2;
            });

            for (auto& mach : machineVector)
            {
                if (mach->AddJob(job))
                {
                    sLog(Console)->Log("Job %s added to machine %s", job->GetName().c_str(), mach->GetName().c_str());
                    _waitingJobs.pop();
                }
            }
        }
    }

    _idleUsers.Update(diff);
}