Skip to content
Snippets Groups Projects
Commit 3ea72523 authored by Maël Madon's avatar Maël Madon
Browse files

dev: finished FeedbackUser, to be tested

parent 30716247
No related branches found
No related tags found
1 merge request!2Feature "replay with feedback" ready and tested
......@@ -8,6 +8,7 @@
void FeedbackUser::init_FeedbackUser(
std::string name, const rapidjson::Value &param)
{
/* Parse some info from the json */
PPK_ASSERT_ERROR(param.HasMember("input_json"),
"Invalid user_description file: wrong 'param' for user %s, there "
"should be an 'input_json' field",
......@@ -19,7 +20,8 @@ void FeedbackUser::init_FeedbackUser(
user_name = name;
input_json = param["input_json"].GetString();
/* open the input file and build the session graph */
/* Open the input file and build the session graph */
Session *start_session
= Parser::session_graph_from_SABjson(user_name, input_json);
......@@ -43,22 +45,74 @@ FeedbackUser::~FeedbackUser()
void FeedbackUser::jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles)
{
// TODO !!
// cette fonction a la charge de
// - produire la liste des jobs
// - mettre à jour la prochaine date
// - mettre à jour les variables annexes
// if (active_session != nullptr)
// {
// double next_job_time = active_session->jobs.front()->submission_time;
// date_of_next_submission = active_session->start_time + next_job_time;
// }
// else
// {
// Session *next_session = free_sessions.top();
// date_of_next_submission = next_session->start_time;
// }
jobs = std::list<Job *>();
profiles = std::list<Profile *>();
if (active_session == nullptr)
{
PPK_ASSERT_ERROR(!free_sessions.empty(),
"User %s has been called to sumbit but she has neither an active "
"session nor free sessions",
user_name.c_str());
PPK_ASSERT_ERROR(free_sessions.top()->start_time <= date,
"Next free session of user %s has greater start time than "
"current date",
user_name.c_str());
active_session = free_sessions.top();
free_sessions.pop();
}
auto job_list = &active_session->jobs;
PPK_ASSERT_ERROR(!job_list->empty(),
"User %s has been called to sumbit but the job list in her active "
"session is empty",
user_name.c_str());
double offset = active_session->start_time;
PPK_ASSERT_ERROR(job_list->front()->submission_time + offset <= date,
"First job in user %s's job list has greater sumbmission time than "
"current date",
user_name.c_str());
/* Submit all jobs that have same submit time */
while (!job_list->empty()
&& job_list->front()->submission_time + offset <= date)
{
Job *job = new Job(*job_list->front()); /* Cast const Job * -> Job * */
Profile *job_profile = new Profile();
/* Handle the job according to the user behavior. */
bool execute_now = handle_job(date, job, job_profile);
if (execute_now)
{
/* Add it to the list of jobs (and profiles, if new) to submit */
jobs.push_back(job);
if (sent_profiles.count(job->profile) == 0)
{
profiles.push_back(job_profile);
sent_profiles.insert(job->profile);
}
ongoing_job_counter++;
/* Delete job from the job list */
job_list->pop_front();
}
}
/* Update next submit time */
if (!job_list->empty())
date_of_next_submission = job_list->front()->submission_time + offset;
else
{
active_session = nullptr;
if (!free_sessions.empty())
date_of_next_submission = free_sessions.top()->start_time;
else
date_of_next_submission = DATE_UNKNOWN;
}
}
void FeedbackUser::wake_on_feedback(double date, std::list<Job *> &ended_jobs)
......@@ -67,21 +121,24 @@ void FeedbackUser::wake_on_feedback(double date, std::list<Job *> &ended_jobs)
for (Job *j : ended_jobs)
{
j->session->unfinished_jobs--;
PPK_ASSERT_ERROR(ongoing_job_counter > 0,
"Job %s of user %s finished but she had no ongoing jobs",
j->id.c_str(), user_name.c_str());
ongoing_job_counter--;
if (j->session->unfinished_jobs == 0)
close_session(date, j->session);
}
/* Find the next submit time */
if (active_session != nullptr)
{
double next_job_time = active_session->jobs.front()->submission_time;
date_of_next_submission = active_session->start_time + next_job_time;
}
else
/* If no active session, find the next submit time */
if (active_session == nullptr)
{
Session *next_session = free_sessions.top();
date_of_next_submission = next_session->start_time;
if (!free_sessions.empty())
date_of_next_submission = free_sessions.top()->start_time;
else if (ongoing_job_counter > 0)
date_of_next_submission = DATE_UNKNOWN;
else
date_of_next_submission = DATE_NEVER;
}
}
......@@ -122,4 +179,11 @@ void FBUserThinkTimeOnly::close_session(double date, Session *finished_session)
/* The finished session won't be used anymore: free memory */
delete finished_session;
}
bool FBUserThinkTimeOnly::handle_job(double date, Job *job, Profile *profile)
{
Parser::profile_from_duration(
profile, job->profile, user_name, platform_computing_speed);
return true;
}
\ No newline at end of file
......@@ -34,12 +34,23 @@ protected:
*/
virtual void close_session(double date, Session *finished_session) = 0;
/**
* A job has to be submitted according to the replay model. Handle it
* depending on the user behavior and returns if it should still be executed
* now.
*/
virtual bool handle_job(double date, Job *job, Profile *profile) = 0;
protected:
std::string input_json;
/* Keep track of profiles to not send them twice to Batsim */
std::set<std::string> sent_profiles;
unsigned int ongoing_job_counter = 0;
/* A session is "active" if the user is currently submitting from it.
* There is only one active session at a time. */
Session *active_session = nullptr;
/* A session is "free" if its dependancy list is empty and it hasn't started
* yet */
std::priority_queue<Session *, std::vector<Session *>, SessionComparator>
......@@ -64,5 +75,6 @@ public:
// double date, std::list<Job *> &jobs, std::list<Profile *> &profiles);
protected:
virtual void close_session(double date, Session *finished_session);
void close_session(double date, Session *finished_session);
bool handle_job(double date, Job *job, Profile *profile);
};
\ No newline at end of file
......@@ -8,6 +8,7 @@
/* Master class ReplayUser */
void ReplayUser::init_ReplayUser(std::string name, const rapidjson::Value &param)
{
/* Parse some info from the json */
PPK_ASSERT_ERROR(param.HasMember("input_json"),
"Invalid user_description file: wrong 'param' for user %s, there "
"should be an 'input_json' field",
......@@ -19,7 +20,8 @@ void ReplayUser::init_ReplayUser(std::string name, const rapidjson::Value &param
user_name = name;
input_json = param["input_json"].GetString();
/* open the input file and import the workload */
/* Open the input file and import the workload */
original_trace = Parser::job_queue_from_input_json(user_name, input_json);
if (original_trace->is_empty())
......
......@@ -47,7 +47,7 @@ protected:
DMWindow *dm_window = nullptr;
int dm_stat[10] = { 0 };
/* Keep track of already sent profiles */
/* Keep track of profiles to not send them twice to Batsim */
std::set<std::string> sent_profiles;
};
......
......@@ -29,7 +29,7 @@ Session::Session(
unfinished_jobs = nb_jobs;
preceding_sessions = map<Session *, double>();
following_sessions = set<Session *>();
jobs = list<Job *>();
jobs = list<const Job *>();
}
Workload::~Workload()
......
......@@ -73,7 +73,7 @@ struct Session
in the replay with feedback. Also used to store the
projected start time. */
unsigned int unfinished_jobs;
std::list<Job *> jobs; // TODO: job Queue instead? To think...
std::list<const Job *> jobs;
std::map<Session *, double> preceding_sessions; /* pair (Session, t_time) */
std::set<Session *> following_sessions;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment