khanat-opennel-code/code/ryzom/tools/stats_scan/job_manager.cpp
2010-05-06 02:08:41 +02:00

179 lines
4.3 KiB
C++

// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "job_manager.h"
class CFinishedJob: public CJobManager::IJob
{
public:
bool finished() { return true; }
std::string getShortStatus() { return _ShortStatus; }
std::string getStatus() { return _Status; }
void display(NLMISC::CLog* log=NLMISC::InfoLog) { log->displayNL("%s",_Status.c_str()); }
void update() {}
CFinishedJob(CJobManager::IJob* theFinishedJob)
{
if (theFinishedJob==NULL)
return;
_Status=theFinishedJob->getStatus();
_ShortStatus=theFinishedJob->getShortStatus();
}
private:
std::string _Status;
std::string _ShortStatus;
};
CJobManager* CJobManager::getInstance()
{
static CJobManager* mgr=NULL;
if (mgr==NULL)
{
mgr=new CJobManager;
}
return mgr;
}
CJobManager::CJobManager()
{
_Paused=false;
_JobUpdatesPerUpdate=1;
}
void CJobManager::serviceUpdate()
{
if (_Paused)
return;
for (uint32 count=0;count<_JobUpdatesPerUpdate &&!_UnfinishedJobs.empty();++count)
{
nlassert(_UnfinishedJobs.front()<_Jobs.size());
NLMISC::CSmartPtr<IJob>& theJob= _Jobs[_UnfinishedJobs.front()];
if (theJob->finished())
{
// delete the job and replace it with a light weight 'finished job' marker
theJob= new CFinishedJob(theJob);
// remove this job from the list of unfinished jobs
_UnfinishedJobs.pop_front();
// decrement the updates counter to counteract the auto incrment
--count;
}
else
{
theJob->update();
}
}
}
uint32 CJobManager::addJob(NLMISC::CSmartPtr<CJobManager::IJob> job)
{
nlassert(job!=NULL);
uint32 id= _Jobs.size();
_UnfinishedJobs.push_back(id);
_Jobs.push_back(job);
return id;
}
void CJobManager::promoteJob(uint32 idx)
{
TUnfinishedJobs::iterator it;
for (it=_UnfinishedJobs.begin(); it!=_UnfinishedJobs.end(); ++it)
{
if (*it==idx)
{
_UnfinishedJobs.erase(it);
_UnfinishedJobs.push_front(idx);
return;
}
}
nlwarning("Failed to promote job with ID %d as not found in unfinished jobs list",idx);
}
void CJobManager::pause()
{
_Paused= true;
}
void CJobManager::resume()
{
_Paused= false;
}
void CJobManager::setJobUpdatesPerUpdate(uint32 count)
{
_JobUpdatesPerUpdate= count;
if (count==0 || count>100)
nlwarning("Suspicious value of JobUpdatesPerUpdate: %d",count);
}
uint32 CJobManager::getJobUpdatesPerUpdate()
{
return _JobUpdatesPerUpdate;
}
std::string CJobManager::getStatus()
{
std::string result;
if (_Paused) result+="[Paused] ";
if (!_UnfinishedJobs.empty())
{
uint32 idx=_UnfinishedJobs.front();
nlassert(idx<_Jobs.size());
result+=_Jobs[idx]->getStatus();
}
result+=NLMISC::toString(" [Updates per cycle: %d]",_JobUpdatesPerUpdate);
return result;
}
void CJobManager::listJobs(NLMISC::CLog* log)
{
for (uint32 i=0;i< _Jobs.size(); ++i)
{
if (!_Jobs[i]->finished())
nlinfo("%4d*: %s",i,_Jobs[i]->getStatus().c_str());
}
nlinfo("%d unfinished jobs (%d in total)",_UnfinishedJobs.size(),_Jobs.size());
}
void CJobManager::listJobHistory(NLMISC::CLog* log)
{
for (uint32 i=0;i< _Jobs.size(); ++i)
{
nlinfo("%4d%c: %s",i,_Jobs[i]->finished()? ' ': '*',_Jobs[i]->getStatus().c_str());
}
nlinfo("%d unfinished jobs (%d in total)",_UnfinishedJobs.size(),_Jobs.size());
}
void CJobManager::displayCurrentJob(NLMISC::CLog* log)
{
if (!_UnfinishedJobs.empty())
displayJob(_UnfinishedJobs.front(),log);
}
void CJobManager::displayJob(uint32 jobId,NLMISC::CLog* log)
{
nlassert(jobId<_Jobs.size());
_Jobs[jobId]->display(log);
}