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

dev: changes to allow multiple simulatneous active sessions, issue#8

parent cb516723
Branches main
1 merge request!9Several active sessions
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include "../pempek_assert.hpp" #include "../pempek_assert.hpp"
#include "json_workload.hpp" #include "json_workload.hpp"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include <limits>
#include <string> #include <string>
/* FeedbackUser */ /* FeedbackUser */
...@@ -42,78 +43,108 @@ FeedbackUser::~FeedbackUser() ...@@ -42,78 +43,108 @@ FeedbackUser::~FeedbackUser()
{ {
} }
void FeedbackUser::update_date_next_sub()
{
/* Calculate the date of next submission.
* next_submit_time = DATE_UNKNOWN || DATE_NEVER ||
min(free_session->next, active_session->next) */
if (active_sessions.empty()){
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;
return;
}
/* Case active_sessions not empty: the next submit time is known.
* Calculate the min. */
date_of_next_submission = std::numeric_limits<double>::max();
for (Session *active_sess : active_sessions)
{
PPK_ASSERT_ERROR(!active_sess->jobs.empty(),
"Active session %d has no job to submit", active_sess->id);
double next_call = active_sess->start_time +
active_sess->jobs.front()->submission_time;
date_of_next_submission = std::min(date_of_next_submission, next_call);
}
if (!free_sessions.empty())
date_of_next_submission = std::min(date_of_next_submission,
free_sessions.top()->start_time);
return;
}
void FeedbackUser::jobs_to_submit( void FeedbackUser::jobs_to_submit(
double date, std::list<Job *> &jobs, std::list<Profile *> &profiles) double date, std::list<Job *> &jobs, std::list<Profile *> &profiles)
{ {
jobs = std::list<Job *>(); jobs = std::list<Job *>();
profiles = std::list<Profile *>(); profiles = std::list<Profile *>();
if (active_session == nullptr) /* Add the free sessions starting now to the list of active sessions */
while (!free_sessions.empty() && free_sessions.top()->start_time <= date)
{ {
PPK_ASSERT_ERROR(!free_sessions.empty(), active_sessions.push_back(free_sessions.top());
"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(); free_sessions.pop();
} }
PPK_ASSERT_ERROR(!active_sessions.empty(),
auto job_list = &active_session->jobs; "User %s has been called to sumbit but she has no active session",
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()); 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 */ /* For each active session, add the jobs to submit now to the list `jobs` */
while (!job_list->empty() for (auto iter = active_sessions.begin(); iter != active_sessions.end();)
&& job_list->front()->submission_time + offset <= date)
{ {
Job *job = new Job(*job_list->front()); /* Cast const Job * -> Job * */ Session *active_sess = *iter;
Profile *job_profile = new Profile(); auto job_list = &active_sess->jobs;
PPK_ASSERT_ERROR(!job_list->empty(),
"Active session %d has no job to submit", active_sess->id);
/* Handle the job according to the user behavior. */ double offset = active_sess->start_time;
bool execute_now = handle_job(date, job, job_profile);
if (execute_now) while (!job_list->empty()
&& job_list->front()->submission_time + offset <= date)
{ {
job->submission_time = date; Job *job = new Job(*job_list->front()); // Cast const Job * -> Job *
/* Add it to the list of jobs (and profiles, if new) to submit */ Profile *job_profile = new Profile();
jobs.push_back(job);
if (sent_profiles.count(job->profile) == 0) /* Handle the job according to the user behavior. */
bool execute_now = handle_job(date, job, job_profile);
if (execute_now)
{ {
profiles.push_back(job_profile); job->submission_time = date;
sent_profiles.insert(job->profile); /* 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();
} }
ongoing_job_counter++;
/* Delete job from the job list */
job_list->pop_front();
} }
}
/* Update next submit time */ if (job_list->empty()) /* active session finished: close it */
if (!job_list->empty()) iter = active_sessions.erase(iter);
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 else
date_of_next_submission = DATE_UNKNOWN; ++iter;
} }
PPK_ASSERT_ERROR(!jobs.empty(),
"User %s called to submit but did not submit any job",
user_name.c_str());
/* Update next submit time */
update_date_next_sub();
} }
void FeedbackUser::wake_on_feedback(double date, std::list<Job *> &ended_jobs) void FeedbackUser::wake_on_feedback(double date, std::list<Job *> &ended_jobs)
...@@ -131,16 +162,8 @@ void FeedbackUser::wake_on_feedback(double date, std::list<Job *> &ended_jobs) ...@@ -131,16 +162,8 @@ void FeedbackUser::wake_on_feedback(double date, std::list<Job *> &ended_jobs)
close_session(date, j->session); close_session(date, j->session);
} }
/* If no active session, find the next submit time */ /* The next submit time might have changed in reaction to feedback */
if (active_session == nullptr) update_date_next_sub();
{
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;
}
} }
/* FBUserThinkTimeOnly */ /* FBUserThinkTimeOnly */
......
...@@ -28,6 +28,11 @@ protected: ...@@ -28,6 +28,11 @@ protected:
*/ */
void init_FeedbackUser(std::string name, const rapidjson::Value &param); void init_FeedbackUser(std::string name, const rapidjson::Value &param);
/**
* Method to update the date of the next submission of the user
*/
void update_date_next_sub();
/** /**
* A session has finished (all its jobs finished). Update its following * A session has finished (all its jobs finished). Update its following
* sessions and the free sessions depending on the replay model. * sessions and the free sessions depending on the replay model.
...@@ -47,9 +52,8 @@ protected: ...@@ -47,9 +52,8 @@ protected:
std::set<std::string> sent_profiles; std::set<std::string> sent_profiles;
unsigned int ongoing_job_counter = 0; unsigned int ongoing_job_counter = 0;
/* A session is "active" if the user is currently submitting from it. /* A session is "active" if the user is currently submitting from it */
* There is only one active session at a time. */ std::list<Session *> active_sessions;
Session *active_session = nullptr;
/* A session is "free" if its dependancy list is empty and it hasn't started /* A session is "free" if its dependancy list is empty and it hasn't started
* yet */ * yet */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment