Back to index

nordugrid-arc-nox  1.1.0~rc6
Public Types | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes
JobsList Class Reference

#include <states.h>

Collaboration diagram for JobsList:
Collaboration graph
[legend]

List of all members.

Public Types

typedef std::list
< JobDescription >::iterator 
iterator

Public Member Functions

 JobsList (JobUser &user, ContinuationPlugins &plugins)
 ~JobsList (void)
iterator FindJob (const JobId &id)
iterator begin (void)
iterator end (void)
size_t size (void) const
bool AddJob (JobUser &user, const JobId &id, uid_t uid, gid_t gid)
bool AddJob (const JobId &id, uid_t uid, gid_t gid)
bool ActJob (const JobId &id, bool hard_job=false)
bool ActJob (iterator &i, bool hard_job=false)
void CalculateShares ()
bool ActJobs (bool hard_job=false)
bool ScanNewJobs (bool hard_job=false)
bool DestroyJobs (bool finished=true, bool active=true)
bool GetLocalDescription (const JobsList::iterator &i)
void ActJobUndefined (iterator &i, bool hard_job, bool &once_more, bool &delete_job, bool &job_error, bool &state_changed)
void ActJobAccepted (iterator &i, bool hard_job, bool &once_more, bool &delete_job, bool &job_error, bool &state_changed)
void ActJobPreparing (iterator &i, bool hard_job, bool &once_more, bool &delete_job, bool &job_error, bool &state_changed)
void ActJobSubmitting (iterator &i, bool hard_job, bool &once_more, bool &delete_job, bool &job_error, bool &state_changed)
void ActJobCanceling (iterator &i, bool hard_job, bool &once_more, bool &delete_job, bool &job_error, bool &state_changed)
void ActJobInlrms (iterator &i, bool hard_job, bool &once_more, bool &delete_job, bool &job_error, bool &state_changed)
void ActJobFinishing (iterator &i, bool hard_job, bool &once_more, bool &delete_job, bool &job_error, bool &state_changed)
void ActJobFinished (iterator &i, bool hard_job, bool &once_more, bool &delete_job, bool &job_error, bool &state_changed)
void ActJobDeleted (iterator &i, bool hard_job, bool &once_more, bool &delete_job, bool &job_error, bool &state_changed)

Static Public Member Functions

static void SetMaxJobs (int max=-1, int max_running=-1)
static void SetMaxJobsLoad (int max_processing=-1, int max_processing_emergency=1, int max_down=-1)
static void GetMaxJobs (int &max, int &max_running)
static void GetMaxJobsLoad (int &max_processing, int &max_processing_emergency, int &max_down)
static void SetSpeedControl (unsigned long long int min=0, time_t min_time=300, unsigned long long int min_average=0, time_t max_time=300)
static void SetSecureTransfer (bool val)
static void SetPassiveTransfer (bool val)
static void SetLocalTransfer (bool val)
static void SetWakeupPeriod (unsigned int t)
static unsigned int WakeupPeriod (void)
static void SetMaxRetries (int r)
static int MaxRetries ()
static void SetTransferShare (unsigned int max_share, std::string type)
static bool AddLimitedShare (std::string share_name, unsigned int share_limit)

Private Member Functions

bool AddJobNoCheck (const JobId &id, iterator &i, uid_t uid, gid_t gid)
bool AddJobNoCheck (const JobId &id, uid_t uid, gid_t gid)
bool FailedJob (const iterator &i)
bool DestroyJob (iterator &i, bool finished=true, bool active=true)
bool state_submitting (const iterator &i, bool &state_changed, bool cancel=false)
bool state_loading (const iterator &i, bool &state_changed, bool up, bool &retry)
bool JobPending (JobsList::iterator &i)
job_state_t JobFailStateGet (const iterator &i)
bool JobFailStateRemember (const iterator &i, job_state_t state)
bool RecreateTransferLists (const JobsList::iterator &i)

Private Attributes

std::list< JobDescriptionjobs
std::map< std::string, int > preparing_job_share
std::map< std::string, int > finishing_job_share
std::map< std::string, int > preparing_max_share
std::map< std::string, int > finishing_max_share
JobUseruser
ContinuationPluginsplugins

Static Private Attributes

static int jobs_num [JOB_STATE_NUM] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
static int jobs_pending = 0
static int max_jobs_running = -1
static int max_jobs_processing = DEFAULT_MAX_JOBS
static int max_jobs_processing_emergency = 1
static int max_jobs = -1
static unsigned int max_processing_share = 0
static std::string share_type = ""
static unsigned long long int min_speed = 0
static time_t min_speed_time = 300
static unsigned long long int min_average_speed = 0
static time_t max_inactivity_time = 300
static int max_downloads = -1
static int max_retries = DEFAULT_MAX_RETRIES
static bool use_secure_transfer = false
static bool use_passive_transfer = false
static bool use_local_transfer = false
static unsigned int wakeup_period = 120
static std::map< std::string, int > limited_share

Detailed Description

Definition at line 40 of file states.h.


Member Typedef Documentation

Definition at line 42 of file states.h.


Constructor & Destructor Documentation

JobsList::JobsList ( JobUser user,
ContinuationPlugins plugins 
)

Definition at line 78 of file states.cpp.

                                                             {
  this->user=&user;
  this->plugins=&plugins;
  jobs.clear();
}
JobsList::~JobsList ( void  )

Definition at line 84 of file states.cpp.

                       {
}

Member Function Documentation

bool JobsList::ActJob ( const JobId id,
bool  hard_job = false 
)

Definition at line 134 of file states.cpp.

                                                    {
  iterator i=FindJob(id);
  if(i == jobs.end()) return false;
  return ActJob(i,hard_job);
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool JobsList::ActJob ( JobsList::iterator i,
bool  hard_job = false 
)

Definition at line 1328 of file states.cpp.

                                                       {
  bool once_more     = true;
  bool delete_job    = false;
  bool job_error     = false;
  bool state_changed = false;
  job_state_t old_state = i->job_state;
  bool old_pending = i->job_pending;
  while(once_more) {
    once_more     = false;
    delete_job    = false;
    job_error     = false;
    state_changed = false;
 /* some states can not be canceled (or there is no sense to do that) */
/*
       (i->job_state != JOB_STATE_FINISHING) &&
*/
    if((i->job_state != JOB_STATE_CANCELING) &&
       (i->job_state != JOB_STATE_FINISHED) &&
       (i->job_state != JOB_STATE_DELETED) &&
       (i->job_state != JOB_STATE_SUBMITTING)) {
      if(job_cancel_mark_check(i->job_id,*user)) {
        logger.msg(Arc::INFO,"%s: Canceling job (%s) because of user request",i->job_id,user->UnixName());
        /* kill running child */
        if(i->child) { 
          i->child->Kill(0);
          delete i->child; i->child=NULL;
        };
        /* update transfer share counters */
          if (i->job_state == JOB_STATE_PREPARING && !i->job_pending) preparing_job_share[i->transfer_share]--;
          else if (i->job_state == JOB_STATE_FINISHING) finishing_job_share[i->transfer_share]--;
        /* put some explanation */
        i->AddFailure("User requested to cancel the job");
        /* behave like if job failed */
        if(!FailedJob(i)) {
          /* DO NOT KNOW WHAT TO DO HERE !!!!!!!!!! */
        };
        /* special processing for INLRMS case */
        if(i->job_state == JOB_STATE_INLRMS) {
          i->job_state = JOB_STATE_CANCELING;
        }
        else if(i->job_state == JOB_STATE_FINISHING) {
          i->job_state = JOB_STATE_FINISHED;
        }
        else {
          i->job_state = JOB_STATE_FINISHING;
          finishing_job_share[i->transfer_share]++;
        };
        job_cancel_mark_remove(i->job_id,*user);
        state_changed=true;
        once_more=true;
      };
    };
    if(!state_changed) switch(i->job_state) {
    /* undefined state - not actual state - job was just added but
       not analyzed yet */
      case JOB_STATE_UNDEFINED: {
       ActJobUndefined(i,hard_job,once_more,delete_job,job_error,state_changed);
      }; break;
      case JOB_STATE_ACCEPTED: {
       ActJobAccepted(i,hard_job,once_more,delete_job,job_error,state_changed);
      }; break;
      case JOB_STATE_PREPARING: {
       ActJobPreparing(i,hard_job,once_more,delete_job,job_error,state_changed);
      }; break;
      case JOB_STATE_SUBMITTING: {
       ActJobSubmitting(i,hard_job,once_more,delete_job,job_error,state_changed);
      }; break;
      case JOB_STATE_CANCELING: {
       ActJobCanceling(i,hard_job,once_more,delete_job,job_error,state_changed);
      }; break;
      case JOB_STATE_INLRMS: {
       ActJobInlrms(i,hard_job,once_more,delete_job,job_error,state_changed);
      }; break;
      case JOB_STATE_FINISHING: {
       ActJobFinishing(i,hard_job,once_more,delete_job,job_error,state_changed);
      }; break;
      case JOB_STATE_FINISHED: {
       ActJobFinished(i,hard_job,once_more,delete_job,job_error,state_changed);
      }; break;
      case JOB_STATE_DELETED: {
       ActJobDeleted(i,hard_job,once_more,delete_job,job_error,state_changed);
      }; break;
      default: { // should destroy job with unknown state ?!
      };
    };
    do {
      // Process errors which happened during processing this job
      if(job_error) {
        job_error=false;
        // always cause rerun - in order not to loose state change
        // Failed job - move it to proper state
        logger.msg(Arc::ERROR,"%s: Job failure detected",i->job_id);
        if(!FailedJob(i)) { /* something is really wrong */
          i->AddFailure("Failed during processing failure");
          delete_job=true;
        } else { /* just move job to proper state */
          if((i->job_state == JOB_STATE_FINISHED) ||
             (i->job_state == JOB_STATE_DELETED)) {
            // Normally these stages should not generate errors
            // so ignore them
          } else if(i->job_state == JOB_STATE_FINISHING) {
            // No matter if FINISHING fails - it still goes to FINISHED
            i->job_state = JOB_STATE_FINISHED;
            state_changed=true;
            once_more=true;
          } else {
            // Any other failure should cause transfer to FINISHING
            i->job_state = JOB_STATE_FINISHING;
            finishing_job_share[i->transfer_share]++;
            state_changed=true;
            once_more=true;
          };
          i->job_pending=false;
        };
      };
      // Process state changes, also those generated by error processing
      if(state_changed) {
        state_changed=false;
        i->job_pending=false;
        // Report state change into log
        logger.msg(Arc::INFO,"%s: State: %s from %s",
              i->job_id.c_str(),JobDescription::get_state_name(i->job_state),
              JobDescription::get_state_name(old_state));
        if(!job_state_write_file(*i,*user,i->job_state)) {
          i->AddFailure("Failed writing job status");
          job_error=true;
        } else {
          // talk to external plugin to ask if we can proceed
          if(plugins) {
            std::list<ContinuationPlugins::result_t> results;
            plugins->run(*i,*user,results);
            std::list<ContinuationPlugins::result_t>::iterator result = results.begin();
            while(result != results.end()) {
              // analyze results
              if(result->action == ContinuationPlugins::act_fail) {
                logger.msg(Arc::ERROR,"%s: Plugin at state %s : %s",
                    i->job_id.c_str(),states_all[i->get_state()].name,
                    result->response);
                i->AddFailure(std::string("Plugin at state ")+
                states_all[i->get_state()].name+" failed: "+(result->response));
                job_error=true;
              } else if(result->action == ContinuationPlugins::act_log) {
                // Scream but go ahead
                logger.msg(Arc::WARNING,"%s: Plugin at state %s : %s",
                    i->job_id.c_str(),states_all[i->get_state()].name,
                    result->response);
              } else if(result->action == ContinuationPlugins::act_pass) {
                // Just continue quietly
              } else {
                logger.msg(Arc::ERROR,"%s: Plugin execution failed",i->job_id);
                i->AddFailure(std::string("Failed running plugin at state ")+
                    states_all[i->get_state()].name);
                job_error=true;
              };
              ++result;
            };
          };
          // Processing to be done on state changes 
          job_log.make_file(*i,*user);
          if(i->job_state == JOB_STATE_FINISHED) {
            if(i->GetLocalDescription(*user)) {
              job_stdlog_move(*i,*user,i->local->stdlog);
            };
            job_clean_finished(i->job_id,*user);
            job_log.finish_info(*i,*user);
            prepare_cleanuptime(i->job_id,i->keep_finished,i,*user);
          } else if(i->job_state == JOB_STATE_PREPARING) {
            job_log.start_info(*i,*user);
          };
        };
        /* send mail after errora and change are processed */
        /* do not send if something really wrong happened to avoid email DoS */
        if(!delete_job) send_mail(*i,*user);
      };
      // Keep repeating till error goes out
    } while(job_error);
    if(delete_job) { 
      logger.msg(Arc::ERROR,"%s: Delete request due to internal problems",i->job_id);
      i->job_state = JOB_STATE_FINISHED; /* move to finished in order to 
                                            remove from list */
      i->job_pending=false;
      job_state_write_file(*i,*user,i->job_state); 
      i->AddFailure("Serious troubles (problems during processing problems)");
      FailedJob(i);  /* put some marks */
      if(i->GetLocalDescription(*user)) {
        job_stdlog_move(*i,*user,i->local->stdlog);
      };
      job_clean_finished(i->job_id,*user);  /* clean status files */
      once_more=true; hard_job=true; /* to process some things in local */
    };
  };
  /* FINISHED+DELETED jobs are not kept in list - only in files */
  /* if job managed to get here with state UNDEFINED - 
     means we are overloaded with jobs - do not keep them in list */
  if((i->job_state == JOB_STATE_FINISHED) ||
     (i->job_state == JOB_STATE_DELETED) ||
     (i->job_state == JOB_STATE_UNDEFINED)) {
    /* this is the ONLY place there jobs are removed from memory */
    /* update counters */
    if(!old_pending) {
      jobs_num[old_state]--;
    } else {
      jobs_pending--;
    };
    if(i->local) { delete i->local; };
    i=jobs.erase(i);
  }
  else {
    /* update counters */
    if(!old_pending) {
      jobs_num[old_state]--;
    } else {
      jobs_pending--;
    };
    if(!i->job_pending) {
      jobs_num[i->job_state]++;
    } else {
      jobs_pending++;
    }
    ++i;
  };
  return true;
}

Here is the call graph for this function:

void JobsList::ActJobAccepted ( JobsList::iterator i,
bool  hard_job,
bool &  once_more,
bool &  delete_job,
bool &  job_error,
bool &  state_changed 
)

Definition at line 924 of file states.cpp.

                                                                   {
      /* accepted state - job was just accepted by jobmager-ng and we already
         know that it is accepted - now we are analyzing/parsing request,
         or it can also happen we are waiting for user specified time */
        logger.msg(Arc::VERBOSE,"%s: State: ACCEPTED",i->job_id);
        if(!GetLocalDescription(i)) {
          job_error=true; i->AddFailure("Internal error");
          return; /* go to next job */
        };
        if(i->local->dryrun) {
          logger.msg(Arc::INFO,"%s: State: ACCEPTED: dryrun",i->job_id);
          i->AddFailure("User requested dryrun. Job skiped.");
          job_error=true; 
          return; /* go to next job */
        };
        if((max_jobs_processing == -1) ||
           (use_local_transfer) ||
           ((i->local->downloads == 0) && (i->local->rtes == 0)) ||
           (((JOB_NUM_PROCESSING < max_jobs_processing) ||
            ((JOB_NUM_FINISHING >= max_jobs_processing) && 
            (JOB_NUM_PREPARING < max_jobs_processing_emergency))) &&
           (i->next_retry <= time(NULL)) && 
           (share_type.empty() || preparing_job_share[i->transfer_share] < preparing_max_share[i->transfer_share])))
        {
          /* check for user specified time */
          if(i->retries == 0 && i->local->processtime != -1) {
            logger.msg(Arc::INFO,"%s: State: ACCEPTED: have processtime %s",i->job_id.c_str(),
                  i->local->processtime.str(Arc::UserTime));
            if((i->local->processtime) <= time(NULL)) {
              logger.msg(Arc::INFO,"%s: State: ACCEPTED: moving to PREPARING",i->job_id);
              state_changed=true; once_more=true;
              i->job_state = JOB_STATE_PREPARING;
              i->retries = JobsList::max_retries;
              preparing_job_share[i->transfer_share]++;
            };
          }
          else {
            logger.msg(Arc::INFO,"%s: State: ACCEPTED: moving to PREPARING",i->job_id);
            state_changed=true; once_more=true;
            i->job_state = JOB_STATE_PREPARING;
            /* if first pass then reset retries */
            if (i->retries ==0) i->retries = JobsList::max_retries;
            preparing_job_share[i->transfer_share]++;
          };
          if(state_changed && i->retries == JobsList::max_retries) {
            /* gather some frontend specific information for user,
               do it only once */
            std::string cmd = nordugrid_libexec_loc()+"/frontend-info-collector";
            char const * const args[2] = { cmd.c_str(), NULL };
            job_controldiag_mark_put(*i,*user,args);
          };
        } else JobPending(i);
        return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void JobsList::ActJobCanceling ( JobsList::iterator i,
bool  hard_job,
bool &  once_more,
bool &  delete_job,
bool &  job_error,
bool &  state_changed 
)

Definition at line 1051 of file states.cpp.

                                                                    {
        /* This state is like submitting, only -rm instead of -submit */
        logger.msg(Arc::VERBOSE,"%s: State: CANCELING",i->job_id);
        if(state_submitting(i,state_changed,true)) {
          if(state_changed) {
            i->job_state = JOB_STATE_FINISHING;
            finishing_job_share[i->transfer_share]++;
            once_more=true;
          };
        }
        else { job_error=true; };
        return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void JobsList::ActJobDeleted ( JobsList::iterator i,
bool  hard_job,
bool &  once_more,
bool &  delete_job,
bool &  job_error,
bool &  state_changed 
)

Definition at line 1303 of file states.cpp.

                                              {
        if(hard_job) { /* try to minimize load */
          time_t t = -1;
          if(!job_local_read_cleanuptime(i->job_id,*user,t)) {
            /* should not happen - delete job */
            JobLocalDescription job_desc;
            /* read lifetime - if empty it wont be overwritten */
            job_clean_final(*i,*user);
          } else {
            /* check if it is not time to remove remnants of that */
            if((time(NULL)-(t+i->keep_deleted)) >= 0) {
              logger.msg(Arc::INFO,"%s: Job is ancient - delete rest of information",i->job_id);
              /* delete everything */
              job_clean_final(*i,*user);
            };
          };
        };
        return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void JobsList::ActJobFinished ( JobsList::iterator i,
bool  hard_job,
bool &  once_more,
bool &  delete_job,
bool &  job_error,
bool &  state_changed 
)

Definition at line 1205 of file states.cpp.

                                                           {
        if(job_clean_mark_check(i->job_id,*user)) {
          logger.msg(Arc::INFO,"%s: Job is requested to clean - deleting",i->job_id);
          /* delete everything */
          job_clean_final(*i,*user);
        } else {
          if(job_restart_mark_check(i->job_id,*user)) { 
            job_restart_mark_remove(i->job_id,*user); 
            /* request to rerun job - check if can */
            // Get information about failed state and forget it
            job_state_t state_ = JobFailStateGet(i);
            if(state_ == JOB_STATE_PREPARING) {
              if(RecreateTransferLists(i)) {
                job_failed_mark_remove(i->job_id,*user);
                // state_changed=true;
                i->job_state = JOB_STATE_ACCEPTED;
                JobPending(i); // make it go to end of state immediately
                return;
              };
            } else if((state_ == JOB_STATE_SUBMITTING) ||
                      (state_ == JOB_STATE_INLRMS)) {
              if(RecreateTransferLists(i)) {
                job_failed_mark_remove(i->job_id,*user);
                // state_changed=true;
                if((i->local->downloads > 0) || (i->local->rtes > 0)) {
                  // missing input files has to be re-downloaded
                  i->job_state = JOB_STATE_ACCEPTED;
                } else {
                  i->job_state = JOB_STATE_PREPARING;
                };
                JobPending(i); // make it go to end of state immediately
                return;
              };
            } else if(state_ == JOB_STATE_FINISHING) {
              if(RecreateTransferLists(i)) {
                job_failed_mark_remove(i->job_id,*user);
                // state_changed=true;
                i->job_state = JOB_STATE_INLRMS;
                JobPending(i); // make it go to end of state immediately
                return;
              };
            } else {
              logger.msg(Arc::ERROR,"%s: Can't rerun on request - not a suitable state",i->job_id);
            };
          };
          if(hard_job) { /* try to minimize load */
            time_t t = -1;
            if(!job_local_read_cleanuptime(i->job_id,*user,t)) {
              /* must be first time - create cleanuptime */
              t=prepare_cleanuptime(i->job_id,i->keep_finished,i,*user);
            };
            /* check if it is not time to remove that job completely */
            if((time(NULL)-t) >= 0) {
              logger.msg(Arc::INFO,"%s: Job is too old - deleting",i->job_id);
              if(i->keep_deleted) {
                // here we have to get the cache per-job dirs to be deleted
                CacheConfig * cache_config;
                std::list<std::string> cache_per_job_dirs;
                try {
                  cache_config = new CacheConfig();
                }
                catch (CacheConfigException e) {
                  logger.msg(Arc::ERROR, "Error with cache configuration: %s", e.what());
                  job_clean_deleted(*i,*user);
                  i->job_state = JOB_STATE_DELETED;
                  state_changed=true;
                  return;
                }
                std::vector<std::string> conf_caches = cache_config->getCacheDirs();
                // add each dir to our list
                for (std::vector<std::string>::iterator it = conf_caches.begin(); it != conf_caches.end(); it++) {
                  cache_per_job_dirs.push_back(it->substr(0, it->find(" "))+"/joblinks");
                }
                // add remote caches
                std::vector<std::string> remote_caches = cache_config->getRemoteCacheDirs();
                for (std::vector<std::string>::iterator it = remote_caches.begin(); it != remote_caches.end(); it++) {
                  cache_per_job_dirs.push_back(it->substr(0, it->find(" "))+"/joblinks");
                }
                // add draining caches
                std::vector<std::string> draining_caches = cache_config->getDrainingCacheDirs();
                for (std::vector<std::string>::iterator it = draining_caches.begin(); it != draining_caches.end(); it++) {
                  cache_per_job_dirs.push_back(it->substr(0, it->find(" "))+"/joblinks");
                }
                job_clean_deleted(*i,*user,cache_per_job_dirs);
                i->job_state = JOB_STATE_DELETED;
                state_changed=true;
              } else {
                /* delete everything */
                job_clean_final(*i,*user);
              };
            };
          };
        };
        return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void JobsList::ActJobFinishing ( JobsList::iterator i,
bool  hard_job,
bool &  once_more,
bool &  delete_job,
bool &  job_error,
bool &  state_changed 
)

Definition at line 1147 of file states.cpp.

                                                                    {
        logger.msg(Arc::VERBOSE,"%s: State: FINISHING",i->job_id);
        bool retry = false;
        if(state_loading(i,state_changed,true,retry)) {
          if (retry) {
            finishing_job_share[i->transfer_share]--;
            if(--i->retries == 0) { // no tries left
              logger.msg(Arc::ERROR,"%s: Upload failed. No retries left.",i->job_id);
              i->AddFailure("uploader failed (post-processing)");
              job_error=true;
              JobFailStateRemember(i,JOB_STATE_FINISHING);
              return;
            };
            /* set next retry time
            exponential back-off algorithm - wait 10s, 40s, 90s, 160s,...
            with a bit of randomness thrown in - vary by up to 50% of wait_time */
            int wait_time = 10 * (JobsList::max_retries - i->retries) * (JobsList::max_retries - i->retries);
            int randomness = (rand() % wait_time) - (wait_time/2);
            wait_time += randomness;
            i->next_retry = time(NULL) + wait_time;
            logger.msg(Arc::ERROR,"%s: Upload failed. %d retries left. Will wait for %ds before retrying.",i->job_id,i->retries,wait_time);
            /* set back to INLRMS */
            i->job_state = JOB_STATE_INLRMS;
            state_changed = true;
          }
          else if(state_changed) {
            finishing_job_share[i->transfer_share]--;
            i->job_state = JOB_STATE_FINISHED;
            once_more=true; hard_job=true;
          };
        } else {
          // i->job_state = JOB_STATE_FINISHED;
          state_changed=true; /* to send mail */
          once_more=true; hard_job=true;
          if(i->GetFailure().length() == 0)
            i->AddFailure("uploader failed (post-processing)");
          job_error=true;
          finishing_job_share[i->transfer_share]--;
          return; /* go to next job */
        };
        return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void JobsList::ActJobInlrms ( JobsList::iterator i,
bool  hard_job,
bool &  once_more,
bool &  delete_job,
bool &  job_error,
bool &  state_changed 
)

Definition at line 1067 of file states.cpp.

                                                                 {
        logger.msg(Arc::VERBOSE,"%s: State: INLRMS",i->job_id);
        if(!GetLocalDescription(i)) {
          i->AddFailure("Failed reading local job information");
          job_error=true;
          return; /* go to next job */
        };
        /* only check lrms job status on first pass */
        if(i->retries == 0 || i->retries == JobsList::max_retries) {
          if(i->job_pending || job_lrms_mark_check(i->job_id,*user)) {
            if(!i->job_pending) {
              logger.msg(Arc::INFO,"%s: Job finished",i->job_id);
              job_diagnostics_mark_move(*i,*user);
              LRMSResult ec = job_lrms_mark_read(i->job_id,*user);
              if(ec.code() != 0) {
                logger.msg(Arc::INFO,"%s: State: INLRMS: exit message is %i %s",i->job_id,ec.code(),ec.description());
              /*
              * check if not asked to rerun job *
              JobLocalDescription *job_desc = i->local;
              if(job_desc->reruns > 0) { * rerun job once more *
                job_desc->reruns--;
                job_desc->localid="";
                job_local_write_file(*i,*user,*job_desc);
                job_lrms_mark_remove(i->job_id,*user);
                logger.msg(Arc::INFO,"%s: State: INLRMS: job restarted",i->job_id);
                i->job_state = JOB_STATE_SUBMITTING; 
                // INLRMS slot is already taken by this job, so resubmission
                // can be done without any checks
              } else {
              */
                i->AddFailure("LRMS error: ("+
                      Arc::tostring(ec.code())+") "+ec.description());
                job_error=true;
                //i->job_state = JOB_STATE_FINISHING;
                JobFailStateRemember(i,JOB_STATE_INLRMS);
                // This does not require any special postprocessing and
                // can go to next state directly
              /*
              };
              */
                state_changed=true; once_more=true;
                return;
              } else {
              // i->job_state = JOB_STATE_FINISHING;
              };
            };
            if((max_jobs_processing == -1) ||
              (use_local_transfer) ||
              (i->local->uploads == 0) ||
              (((JOB_NUM_PROCESSING < max_jobs_processing) ||
               ((JOB_NUM_PREPARING >= max_jobs_processing) &&
                (JOB_NUM_FINISHING < max_jobs_processing_emergency))) &&
               (i->next_retry <= time(NULL)) &&
               (share_type.empty() || finishing_job_share[i->transfer_share] < finishing_max_share[i->transfer_share]))) {
                 state_changed=true; once_more=true;
                 i->job_state = JOB_STATE_FINISHING;
                 /* if first pass then reset retries */
                 if (i->retries == 0) i->retries = JobsList::max_retries;
                 finishing_job_share[i->transfer_share]++;
            } else JobPending(i);
          };
        } else if((max_jobs_processing == -1) ||
                  (use_local_transfer) ||
                  (i->local->uploads == 0) ||
                  (((JOB_NUM_PROCESSING < max_jobs_processing) ||
                   ((JOB_NUM_PREPARING >= max_jobs_processing) &&
                    (JOB_NUM_FINISHING < max_jobs_processing_emergency))) &&
                  (i->next_retry <= time(NULL)) &&
                  (share_type.empty() || finishing_job_share[i->transfer_share] < finishing_max_share[i->transfer_share]))) {
                    state_changed=true; once_more=true;
                    i->job_state = JOB_STATE_FINISHING;
                    finishing_job_share[i->transfer_share]++;
          } else {
              JobPending(i);
          };
        return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void JobsList::ActJobPreparing ( JobsList::iterator i,
bool  hard_job,
bool &  once_more,
bool &  delete_job,
bool &  job_error,
bool &  state_changed 
)

Definition at line 981 of file states.cpp.

                                                                    {
        /* preparing state - means job is parsed and we are going to download or
           already downloading input files. process downloader is run for
           that. it also checks for files user interface have to upload itself*/
        logger.msg(Arc::VERBOSE,"%s: State: PREPARING",i->job_id);
        bool retry = false;
        if(i->job_pending || state_loading(i,state_changed,false,retry)) {
          if(i->job_pending || state_changed) {
            if (state_changed) preparing_job_share[i->transfer_share]--;
            if((JOB_NUM_RUNNING<max_jobs_running) || (max_jobs_running==-1)) {
              i->job_state = JOB_STATE_SUBMITTING;
              state_changed=true; once_more=true;
              i->retries = JobsList::max_retries;
            } else {
              state_changed=false;
              JobPending(i);
            };
          }
          else if (retry){
            preparing_job_share[i->transfer_share]--;
            if(--i->retries == 0) { // no tries left
              logger.msg(Arc::ERROR,"%s: Download failed. No retries left.",i->job_id);
              i->AddFailure("downloader failed (pre-processing)");
              job_error=true;
              JobFailStateRemember(i,JOB_STATE_PREPARING);
              return;
            }
            /* set next retry time
               exponential back-off algorithm - wait 10s, 40s, 90s, 160s,...
               with a bit of randomness thrown in - vary by up to 50% of wait_time */
            int wait_time = 10 * (JobsList::max_retries - i->retries) * (JobsList::max_retries - i->retries);
            int randomness = (rand() % wait_time) - (wait_time/2);
            wait_time += randomness;
            i->next_retry = time(NULL) + wait_time;
            logger.msg(Arc::ERROR,"%s: Download failed. %d retries left. Will wait for %ds before retrying",i->job_id,i->retries,wait_time);
            /* set back to ACCEPTED */
            i->job_state = JOB_STATE_ACCEPTED;
            state_changed = true;
          }; 
        } 
        else {
          if(i->GetFailure().length() == 0)
            i->AddFailure("downloader failed (pre-processing)");
          job_error=true;
          preparing_job_share[i->transfer_share]--;
          return; /* go to next job */
        };
        return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool JobsList::ActJobs ( bool  hard_job = false)

Definition at line 267 of file states.cpp.

                                    {
/*
   * Need to calculate the shares here here because in the ActJob*
   * methods we don't have an overview of all jobs.
   * In those methods we check the share to see if each
   * job can proceed.
*/
  if (!JobsList::share_type.empty() && max_processing_share > 0) {
    CalculateShares();
  } 

  bool res = true;
  bool once_more = false;
  bool postpone_preparing = false;
  bool postpone_finishing = false;
  if((max_jobs_processing != -1) && 
     (!use_local_transfer) && 
     ((JOB_NUM_PROCESSING*3) > (max_jobs_processing*2))) {
    if(JOB_NUM_PREPARING > JOB_NUM_FINISHING) { 
      postpone_preparing=true; 
    } else if(JOB_NUM_PREPARING < JOB_NUM_FINISHING) {
      postpone_finishing=true;
    };
  };
  // first pass - optionally skipping some states
  for(iterator i=jobs.begin();i!=jobs.end();) {
    if(i->job_state == JOB_STATE_UNDEFINED) { once_more=true; }
    else if(((i->job_state == JOB_STATE_ACCEPTED) && postpone_preparing) ||
            ((i->job_state == JOB_STATE_INLRMS) && postpone_finishing)  ) {
      once_more=true;
      i++; continue;
    };
    res &= ActJob(i,hard_job);
  };

  /* Recalculation of the shares before the second pass
   * to update the shares that appeared as a result of 
   * moving some jobs to ACCEPTED during the first pass
  */
  if (!JobsList::share_type.empty() && max_processing_share > 0) {
    CalculateShares();
  }

  // second pass - process skipped states and new jobs
  if(once_more) for(iterator i=jobs.begin();i!=jobs.end();) {
    res &= ActJob(i,hard_job);
  };
  return res;
}

Here is the call graph for this function:

void JobsList::ActJobSubmitting ( JobsList::iterator i,
bool  hard_job,
bool &  once_more,
bool &  delete_job,
bool &  job_error,
bool &  state_changed 
)

Definition at line 1033 of file states.cpp.

                                                                     {
        /* state submitting - everything is ready for submission - 
           so run submission */
        logger.msg(Arc::VERBOSE,"%s: State: SUBMITTING",i->job_id);
        if(state_submitting(i,state_changed)) {
          if(state_changed) {
            i->job_state = JOB_STATE_INLRMS;
            once_more=true;
          };
        } else {
          job_error=true;
          return; /* go to next job */
        };
        return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void JobsList::ActJobUndefined ( JobsList::iterator i,
bool  hard_job,
bool &  once_more,
bool &  delete_job,
bool &  job_error,
bool &  state_changed 
)

Definition at line 841 of file states.cpp.

                                                        {
        /* read state from file */
        /* undefined means job just detected - read it's status */
        /* but first check if it's not too many jobs in system  */
        if((JOB_NUM_ACCEPTED < max_jobs) || (max_jobs == -1)) {
          job_state_t new_state=job_state_read_file(i->job_id,*user);
          if(new_state == JOB_STATE_UNDEFINED) { /* something failed */
            logger.msg(Arc::ERROR,"%s: Reading status of new job failed",i->job_id);
            job_error=true; i->AddFailure("Failed reading status of the job");
            return;
          };
          //  By keeping once_more==false jobs does not cycle here but
          // goes out and registers it's state in counters. This allows
          // to maintain limits properly after restart. Except FINISHED
          // jobs because they are not kept in memory and should be 
          // processed immediately.
          i->job_state = new_state; /* this can be any state, if we are
                                         recovering after failure */
          if(new_state == JOB_STATE_ACCEPTED) {
            // parse request (do it here because any other processing can 
            // read 'local' and then we never know if it was new job)
            JobLocalDescription *job_desc;
            job_desc = new JobLocalDescription;
            job_desc->sessiondir=i->session_dir;
            /* first phase of job - just  accepted - parse request */
            logger.msg(Arc::INFO,"%s: State: ACCEPTED: parsing job description",i->job_id);
            if(!process_job_req(*user,*i,*job_desc)) {
              logger.msg(Arc::ERROR,"%s: Processing job description failed",i->job_id);
              job_error=true; i->AddFailure("Could not process job description");
              delete job_desc;
              return; /* go to next job */
            };
            i->local=job_desc;
            // set transfer share
            if (!share_type.empty()) {
              std::string user_proxy_file = job_proxy_filename(i->get_id(), *user).c_str();
              std::string cert_dir = "/etc/grid-security/certificates";
              std::string v = cert_dir_loc();
              if(! v.empty()) cert_dir = v;
                Arc::Credential u(user_proxy_file,"",cert_dir,"");
                const std::string share = get_property(u,share_type);
                i->set_share(share);
                logger.msg(Arc::INFO, "%s: adding to transfer share %s",i->get_id(),i->transfer_share);
            }
            job_desc->transfershare = i->transfer_share;
            job_local_write_file(*i,*user,*job_desc);
            i->local->transfershare=i->transfer_share;

            // prepare information for logger
            job_log.make_file(*i,*user);
          } else if(new_state == JOB_STATE_FINISHED) {
            once_more=true;
          } else if(new_state == JOB_STATE_DELETED) {
            once_more=true;
          } else {
            logger.msg(Arc::INFO,"%s: %s: New job belongs to %i/%i",i->job_id.c_str(),
                JobDescription::get_state_name(new_state),i->get_uid(),i->get_gid());
            // Make it clean state after restart
            job_state_write_file(*i,*user,i->job_state);
            i->retries = JobsList::max_retries;
            // set transfer share and counters
            JobLocalDescription job_desc;
            if (!share_type.empty()) {
              std::string user_proxy_file = job_proxy_filename(i->get_id(), *user).c_str();
              std::string cert_dir = "/etc/grid-security/certificates";
              std::string v = cert_dir_loc();
              if(! v.empty()) cert_dir = v;
                Arc::Credential u(user_proxy_file,"",cert_dir,"");
                const std::string share = get_property(u,share_type);
                i->set_share(share);
                logger.msg(Arc::INFO, "%s: adding to transfer share %s",i->get_id(),i->transfer_share);
            }
            job_desc.transfershare = i->transfer_share;
            job_local_write_file(*i,*user,job_desc);
            if (new_state == JOB_STATE_PREPARING) preparing_job_share[i->transfer_share]++;
            if (new_state == JOB_STATE_FINISHING) finishing_job_share[i->transfer_share]++;
          };
        }; // Not doing JobPending here because that job kind of does not exist.
        return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool JobsList::AddJob ( JobUser user,
const JobId id,
uid_t  uid,
gid_t  gid 
)

Definition at line 120 of file states.cpp.

                                                                      {
  if((&user) != NULL) {
    if((this->user) == NULL) { this->user = &user; }
    else {
      if(this->user != &user) { /* incompatible user */
        return false;
      };
    };
  };
  return AddJob(id,uid,gid);
}
bool JobsList::AddJob ( const JobId id,
uid_t  uid,
gid_t  gid 
)

Definition at line 108 of file states.cpp.

                                                        {
  /* jobs should be unique */
  if(FindJob(id) != jobs.end()) return false;
  logger.msg(Arc::INFO,"%s: Added",id);
  iterator i=jobs.insert(jobs.end(),
         JobDescription(id,user->SessionRoot(id) + "/" + id));
  i->keep_finished=user->KeepFinished();
  i->keep_deleted=user->KeepDeleted();
  i->set_uid(uid,gid);
  return true;
}

Here is the call graph for this function:

bool JobsList::AddJobNoCheck ( const JobId id,
JobsList::iterator i,
uid_t  uid,
gid_t  gid 
) [private]

Definition at line 100 of file states.cpp.

                                                                                   {
  i=jobs.insert(jobs.end(),JobDescription(id,user->SessionRoot(id) + "/" + id));
  i->keep_finished=user->KeepFinished();
  i->keep_deleted=user->KeepDeleted();
  i->set_uid(uid,gid);
  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool JobsList::AddJobNoCheck ( const JobId id,
uid_t  uid,
gid_t  gid 
) [private]

Definition at line 95 of file states.cpp.

                                                               {
  iterator i;
  return AddJobNoCheck(id,i,uid,gid);
}

Here is the call graph for this function:

static bool JobsList::AddLimitedShare ( std::string  share_name,
unsigned int  share_limit 
) [inline, static]

Definition at line 148 of file states.h.

                                                                              {
    if(max_processing_share == 0)
      return false;
    if(share_limit == 0)
      share_limit = max_processing_share;
    limited_share[share_name] = share_limit;
    return true;
  }

Here is the caller graph for this function:

iterator JobsList::begin ( void  ) [inline]

Definition at line 104 of file states.h.

{ return jobs.begin(); };

transfer share calculation - look at current share for preparing and finishing states, then look at jobs ready to go into preparing or finished and set the share. Need to do it here because in the ActJob* methods we don't have an overview of all jobs. In those methods we check the share to see if each job can proceed.

Definition at line 140 of file states.cpp.

                              {
    // clear shares with 0 count
  for (std::map<std::string, int>::iterator i = preparing_job_share.begin(); i != preparing_job_share.end(); i++)
    if (i->second == 0) preparing_job_share.erase(i);
  for (std::map<std::string, int>::iterator i = finishing_job_share.begin(); i != finishing_job_share.end(); i++)
    if (i->second == 0) finishing_job_share.erase(i);

  // counters of current and potential preparing/finishing jobs
  std::map<std::string, int> pre_preparing_job_share = preparing_job_share;
  std::map<std::string, int> pre_finishing_job_share = finishing_job_share;

  for (iterator i=jobs.begin();i!=jobs.end();i++) {
    if (i->job_state == JOB_STATE_ACCEPTED) {
      // is job ready to move to preparing?
      if (i->retries == 0 && i->local->processtime != -1) {
        if (i->local->processtime <= time(NULL)) {
            pre_preparing_job_share[i->transfer_share]++;
        }
      }
      else if (i->next_retry <= time(NULL)) {
        pre_preparing_job_share[i->transfer_share]++;
      }
    }
    else if (i->job_state == JOB_STATE_INLRMS) {
      // is job ready to move to finishing?
      if (job_lrms_mark_check(i->job_id,*user) && i->next_retry <= time(NULL)) {
        pre_finishing_job_share[i->transfer_share]++;
      }
    }
  };
  
  // Now calculate how many of limited transfer shares are active
  // We need to try to preserve the maximum number of transfer threads 
  // for each active limited share. Jobs that belong to limited 
  // shares will be excluded from calculation of a share limit later
  int privileged_total_pre_preparing = 0;
  int privileged_total_pre_finishing = 0;
  int privileged_jobs_processing = 0;
  int privileged_preparing_job_share = 0;
  int privileged_finishing_job_share = 0;
  for (std::map<std::string, int>::iterator i = limited_share.begin(); i != limited_share.end(); i++) {
    if (pre_preparing_job_share.find(i->first) != pre_preparing_job_share.end()) {
      privileged_preparing_job_share++;
      privileged_jobs_processing += i->second;
      privileged_total_pre_preparing += pre_preparing_job_share[i->first];
    }
    if (pre_finishing_job_share.find(i->first) != pre_finishing_job_share.end()) {
      privileged_finishing_job_share++;
      privileged_jobs_processing += i->second;
      privileged_total_pre_finishing += pre_finishing_job_share[i->first];
    }
  }
  int unprivileged_jobs_processing = max_jobs_processing - privileged_jobs_processing;

  // calculate the number of slots that can be allocated per unprivileged share
  // count the total number of unprivileged jobs (pre)preparing
  int total_pre_preparing = 0;
  int unprivileged_preparing_limit;
  int unprivileged_preparing_job_share = pre_preparing_job_share.size() - privileged_preparing_job_share;
  for (std::map<std::string, int>::iterator i = pre_preparing_job_share.begin(); i != pre_preparing_job_share.end(); i++) { 
    total_pre_preparing += i->second;
  }
  // exclude privileged jobs
  total_pre_preparing -= privileged_total_pre_preparing;
  if (max_jobs_processing == -1 || unprivileged_preparing_job_share <= (unprivileged_jobs_processing / max_processing_share))
    unprivileged_preparing_limit = max_processing_share;
  else if (unprivileged_preparing_job_share > unprivileged_jobs_processing || unprivileged_preparing_job_share <= 0)
    unprivileged_preparing_limit = 1;
  else if (total_pre_preparing <= unprivileged_jobs_processing)
    unprivileged_preparing_limit = max_processing_share;
  else
    unprivileged_preparing_limit = unprivileged_jobs_processing / unprivileged_preparing_job_share;

  // count the total number of jobs (pre)finishing
  int total_pre_finishing = 0;
  int unprivileged_finishing_limit;
  int unprivileged_finishing_job_share = pre_finishing_job_share.size() - privileged_finishing_job_share;
  for (std::map<std::string, int>::iterator i = pre_finishing_job_share.begin(); i != pre_finishing_job_share.end(); i++) {
    total_pre_finishing += i->second;
  }
  // exclude privileged jobs
  total_pre_finishing -= privileged_total_pre_finishing;
  if (max_jobs_processing == -1 || unprivileged_finishing_job_share <= (unprivileged_jobs_processing / max_processing_share))
    unprivileged_finishing_limit = max_processing_share;
  else if (unprivileged_finishing_job_share > unprivileged_jobs_processing || unprivileged_finishing_job_share <= 0)
    unprivileged_finishing_limit = 1;
  else if (total_pre_finishing <= unprivileged_jobs_processing)
    unprivileged_finishing_limit = max_processing_share;
  else
    unprivileged_finishing_limit = unprivileged_jobs_processing / unprivileged_finishing_job_share;

  // if there are queued jobs for both preparing and finishing, split the share between the two states
  if (max_jobs_processing > 0 && total_pre_preparing > unprivileged_jobs_processing/2 && total_pre_finishing > unprivileged_jobs_processing/2) {
    unprivileged_preparing_limit = unprivileged_preparing_limit < 2 ? 1 : unprivileged_preparing_limit/2;
    unprivileged_finishing_limit = unprivileged_finishing_limit < 2 ? 1 : unprivileged_finishing_limit/2;
  }

  if (max_jobs_processing > 0 && privileged_total_pre_preparing > privileged_jobs_processing/2 && privileged_total_pre_finishing > privileged_jobs_processing/2)
  for (std::map<std::string, int>::iterator i = limited_share.begin(); i != limited_share.end(); i++)
    i->second = i->second < 2 ? 1 : i->second/2; 
      
  preparing_max_share = pre_preparing_job_share;
  finishing_max_share = pre_finishing_job_share;
  for (std::map<std::string, int>::iterator i = preparing_max_share.begin(); i != preparing_max_share.end(); i++){
    if (limited_share.find(i->first) != limited_share.end())
      i->second = limited_share[i->first];
    else
      i->second = unprivileged_preparing_limit;
  }
  for (std::map<std::string, int>::iterator i = finishing_max_share.begin(); i != finishing_max_share.end(); i++){
    if (limited_share.find(i->first) != limited_share.end())
      i->second = limited_share[i->first];
    else
      i->second = unprivileged_finishing_limit;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool JobsList::DestroyJob ( JobsList::iterator i,
bool  finished = true,
bool  active = true 
) [private]

Definition at line 326 of file states.cpp.

                                                                       {
  logger.msg(Arc::INFO,"%s: Destroying",i->job_id);
  job_state_t new_state=i->job_state;
  if(new_state == JOB_STATE_UNDEFINED) {
    if((new_state=job_state_read_file(i->job_id,*user))==JOB_STATE_UNDEFINED) {
      logger.msg(Arc::ERROR,"%s: Can't read state - no comments, just cleaning",i->job_id);
      job_clean_final(*i,*user);
      if(i->local) { delete i->local; }; i=jobs.erase(i);
      return true;
    };
  };
  i->job_state = new_state;
  if((new_state == JOB_STATE_FINISHED) && (!finished)) { ++i; return true; };
  if(!active) { ++i; return true; };
  if((new_state != JOB_STATE_INLRMS) || 
     (job_lrms_mark_check(i->job_id,*user))) {
    logger.msg(Arc::INFO,"%s: Cleaning control and session directories",i->job_id);
    job_clean_final(*i,*user);
    if(i->local) { delete i->local; }; i=jobs.erase(i);
    return true;
  };
  logger.msg(Arc::INFO,"%s: This job may be still running - canceling",i->job_id);
  bool state_changed = false;
  if(!state_submitting(i,state_changed,true)) {
    logger.msg(Arc::WARNING,"%s: Cancelation failed (probably job finished) - cleaning anyway",i->job_id);
    job_clean_final(*i,*user);
    if(i->local) { delete i->local; }; i=jobs.erase(i);
    return true;
  };
  if(!state_changed) { ++i; return false; }; /* child still running */
  logger.msg(Arc::INFO,"%s: Cancelation probably succeeded - cleaning",i->job_id);
  job_clean_final(*i,*user);
  if(i->local) { delete i->local; };
  i=jobs.erase(i);
  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool JobsList::DestroyJobs ( bool  finished = true,
bool  active = true 
)

Definition at line 317 of file states.cpp.

                                                    {
  bool res = true;
  for(iterator i=jobs.begin();i!=jobs.end();) {
    res &= DestroyJob(i,finished,active);
  };
  return res;
}

Here is the call graph for this function:

iterator JobsList::end ( void  ) [inline]

Definition at line 105 of file states.h.

{ return jobs.end(); };
bool JobsList::FailedJob ( const iterator i) [private]

Definition at line 364 of file states.cpp.

                                                  {
  /* put mark - failed */
  if(!job_failed_mark_put(*i,*user,i->failure_reason)) return false;
  /* make all output files non-uploadable */
  std::list<FileData> fl;
  if(!job_output_read_file(i->job_id,*user,fl)) return true; /* no file - no error */
  for(std::list<FileData>::iterator ifl=fl.begin();ifl!=fl.end();++ifl) {
    // Remove destination without "preserve" option
    std::string value = Arc::URL(ifl->lfn).Option("preserve");
    if(value != "yes") ifl->lfn="";
  };
  if(!job_output_write_file(*i,*user,fl)) return false;
  if(!(i->local)) {
    JobLocalDescription *job_desc = new JobLocalDescription;
    if(!job_local_read_file(i->job_id,*user,*job_desc)) {
      logger.msg(Arc::ERROR,"%s: Failed reading local information",i->job_id);
      delete job_desc;
    }
    else {
      i->local=job_desc;
    };
  };
  if(i->local) {
    i->local->uploads=0;
    job_local_write_file(*i,*user,*(i->local));
  };
  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 87 of file states.cpp.

                                                 {
  iterator i;
  for(i=jobs.begin();i!=jobs.end();++i) {
    if((*i) == id) break;
  };
  return i;
}

Here is the caller graph for this function:

Definition at line 393 of file states.cpp.

                                                            {
  if(!i->GetLocalDescription(*user)) {
    logger.msg(Arc::ERROR,"%s: Failed reading local information",i->job_id);
    return false;
  };
  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void JobsList::GetMaxJobs ( int &  max,
int &  max_running 
) [inline, static]

Definition at line 116 of file states.h.

                                                    {
    max=max_jobs;
    max_running=max_jobs_running;
  };

Here is the caller graph for this function:

static void JobsList::GetMaxJobsLoad ( int &  max_processing,
int &  max_processing_emergency,
int &  max_down 
) [inline, static]

Definition at line 120 of file states.h.

                                                                                              {
    max_processing=max_jobs_processing;
    max_processing_emergency=max_jobs_processing_emergency;
    max_down=max_downloads;
  };

Here is the caller graph for this function:

Definition at line 732 of file states.cpp.

                                                               {
  if(!GetLocalDescription(i)) {
    return JOB_STATE_UNDEFINED;
  };
  if(i->local->failedstate.length() == 0) { return JOB_STATE_UNDEFINED; };
  for(int n = 0;states_all[n].name != NULL;n++) {
    if(!strcmp(states_all[n].name,i->local->failedstate.c_str())) {
      i->local->failedstate="";
      if(i->local->reruns <= 0) {
        logger.msg(Arc::ERROR,"%s: Job is not allowed to be rerun anymore",i->job_id);
        job_local_write_file(*i,*user,*(i->local));
        return JOB_STATE_UNDEFINED;
      };
      i->local->reruns--;
      job_local_write_file(*i,*user,*(i->local));
      return states_all[n].id;
    };
  };
  logger.msg(Arc::ERROR,"%s: Job failed in unknown state. Won't rerun.",i->job_id);
  i->local->failedstate="";
  job_local_write_file(*i,*user,*(i->local));
  return JOB_STATE_UNDEFINED;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool JobsList::JobFailStateRemember ( const iterator i,
job_state_t  state 
) [private]

Definition at line 819 of file states.cpp.

                                                                               {
  if(!(i->local)) {
    JobLocalDescription *job_desc = new JobLocalDescription;
    if(!job_local_read_file(i->job_id,*user,*job_desc)) {
      logger.msg(Arc::ERROR,"%s: Failed reading local information",i->job_id);
      delete job_desc; return false;
    }
    else {
      i->local=job_desc;
    };
  };
  if(state == JOB_STATE_UNDEFINED) {
    i->local->failedstate="";
    return job_local_write_file(*i,*user,*(i->local));
  };
  if(i->local->failedstate.length() == 0) {
    i->local->failedstate=states_all[state].name;
    return job_local_write_file(*i,*user,*(i->local));
  };
  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool JobsList::JobPending ( JobsList::iterator i) [private]

Definition at line 726 of file states.cpp.

                                             {
  if(i->job_pending) return true;
  i->job_pending=true; 
  return job_state_write_file(*i,*user,i->job_state,true);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int JobsList::MaxRetries ( ) [inline, static]

Definition at line 143 of file states.h.

{ return JobsList::max_retries; };
bool JobsList::RecreateTransferLists ( const JobsList::iterator i) [private]

Definition at line 756 of file states.cpp.

                                                              {
  // Recreate list of output and input files
  std::list<FileData> fl_old;
  std::list<FileData> fl_new;
  std::list<FileData> fi_old;
  std::list<FileData> fi_new;
  // keep local info
  if(!GetLocalDescription(i)) return false;
  // keep current lists
  if(!job_output_read_file(i->job_id,*user,fl_old)) {
    logger.msg(Arc::ERROR,"%s: Failed to read list of output files",i->job_id);
    return false;
  };
  if(!job_input_read_file(i->job_id,*user,fi_old)) {
    logger.msg(Arc::ERROR,"%s: Failed to read list of input files",i->job_id);
    return false;
  };
  // recreate lists by reprocessing RSL 
  JobLocalDescription job_desc; // placeholder
  if(!process_job_req(*user,*i,job_desc)) {
    logger.msg(Arc::ERROR,"%s: Reprocessing RSL failed",i->job_id);
    return false;
  };
  // Restore 'local'
  if(!job_local_write_file(*i,*user,*(i->local))) return false;
  // Read new lists
  if(!job_output_read_file(i->job_id,*user,fl_new)) {
    logger.msg(Arc::ERROR,"%s: Failed to read reprocessed list of output files",i->job_id);
    return false;
  };
  if(!job_input_read_file(i->job_id,*user,fi_new)) {
    logger.msg(Arc::ERROR,"%s: Failed to read reprocessed list of input files",i->job_id);
    return false;
  };
  // remove uploaded files
  i->local->uploads=0;
  for(std::list<FileData>::iterator i_new = fl_new.begin();
                                    i_new!=fl_new.end();) {
    if(!(i_new->has_lfn())) { ++i_new; continue; }; // user file - keep
    std::list<FileData>::iterator i_old = fl_old.begin();
    for(;i_old!=fl_old.end();++i_old) {
      if((*i_new) == (*i_old)) break;
    };
    if(i_old != fl_old.end()) { ++i_new; i->local->uploads++; continue; };
    i_new=fl_new.erase(i_new);
  };
  if(!job_output_write_file(*i,*user,fl_new)) return false;
  // remove existing files
  i->local->downloads=0;
  for(std::list<FileData>::iterator i_new = fi_new.begin();
                                    i_new!=fi_new.end();) {
    std::string path = i->session_dir+"/"+i_new->pfn;
    struct stat st;
    if(::stat(path.c_str(),&st) == -1) {
      ++i_new; i->local->downloads++;
    } else {
      i_new=fi_new.erase(i_new);
    };
  };
  if(!job_input_write_file(*i,*user,fi_new)) return false;
  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool JobsList::ScanNewJobs ( bool  hard_job = false)

Definition at line 1565 of file states.cpp.

                                 {
  std::string file;
  std::string cdir=user->ControlDir();
  std::list<JobFDesc> ids;
  try {
    Glib::Dir dir(cdir);
    for(;;) {
      file=dir.read_name();
      if(file.empty()) break;
      int l=file.length();
      if(l>(4+7)) {  /* job id contains at least 1 character */
        if(!strncmp(file.c_str(),"job.",4)) {
          if(!strncmp((file.c_str())+(l-7),".status",7)) {
            JobFDesc id((file.c_str())+4,l-7-4);
            if(FindJob(id.id) == jobs.end()) {
              std::string fname=cdir+'/'+file.c_str();
              uid_t uid;
              gid_t gid;
              time_t t;
              if(check_file_owner(fname,*user,uid,gid,t)) {
                /* add it to the list */
                id.uid=uid; id.gid=gid; id.t=t;
                ids.push_back(id);
              };
            };
          };
        };
      };
    };
  } catch(Glib::FileError& e) {
    logger.msg(Arc::ERROR,"Failed reading control directory: %s",user->ControlDir());
    return false;
  };
  /* sorting by date */
  ids.sort();
  for(std::list<JobFDesc>::iterator id=ids.begin();id!=ids.end();++id) {
    iterator i;
    /* adding job with file's uid/gid */
    if(AddJobNoCheck(id->id,i,id->uid,id->gid)) {
/*    ActJob(i,hard_job);  */
    };
 /* failed AddJob most probably means it is already in list or limit exceeded */
  };
  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void JobsList::SetLocalTransfer ( bool  val) [inline, static]

Definition at line 137 of file states.h.

                                         {
    use_local_transfer=val;
  };

Here is the caller graph for this function:

static void JobsList::SetMaxJobs ( int  max = -1,
int  max_running = -1 
) [inline, static]

Definition at line 107 of file states.h.

                                                            {
    max_jobs=max;
    max_jobs_running=max_running;
  };

Here is the caller graph for this function:

static void JobsList::SetMaxJobsLoad ( int  max_processing = -1,
int  max_processing_emergency = 1,
int  max_down = -1 
) [inline, static]

Definition at line 111 of file states.h.

                                                                                                         {
    max_jobs_processing=max_processing;
    max_jobs_processing_emergency=max_processing_emergency;
    max_downloads=max_down;
  };

Here is the caller graph for this function:

static void JobsList::SetMaxRetries ( int  r) [inline, static]

Definition at line 142 of file states.h.

Here is the caller graph for this function:

static void JobsList::SetPassiveTransfer ( bool  val) [inline, static]

Definition at line 134 of file states.h.

Here is the caller graph for this function:

static void JobsList::SetSecureTransfer ( bool  val) [inline, static]

Definition at line 131 of file states.h.

Here is the caller graph for this function:

static void JobsList::SetSpeedControl ( unsigned long long int  min = 0,
time_t  min_time = 300,
unsigned long long int  min_average = 0,
time_t  max_time = 300 
) [inline, static]

Definition at line 125 of file states.h.

                                                                                                                                         {
    min_speed = min;
    min_speed_time = min_time;
    min_average_speed = min_average;
    max_inactivity_time = max_time;
  };

Here is the caller graph for this function:

static void JobsList::SetTransferShare ( unsigned int  max_share,
std::string  type 
) [inline, static]

Definition at line 144 of file states.h.

                                                                      {
    max_processing_share = max_share;
    share_type = type;
  };

Here is the caller graph for this function:

static void JobsList::SetWakeupPeriod ( unsigned int  t) [inline, static]

Definition at line 140 of file states.h.

{ wakeup_period=t; };

Here is the caller graph for this function:

size_t JobsList::size ( void  ) const [inline]

Definition at line 106 of file states.h.

{ return jobs.size(); };
bool JobsList::state_loading ( const iterator i,
bool &  state_changed,
bool  up,
bool &  retry 
) [private]

Definition at line 537 of file states.cpp.

                                                                                              {
  /* RSL was analyzed/parsed - now run child process downloader
     to download job input files and to wait for user uploaded ones */
  if(i->child == NULL) { /* no child started */
    logger.msg(Arc::INFO,"%s: state: PREPARING/FINISHING: starting new child",i->job_id);
    /* no child was running yet, or recovering from fault */
    /* run it anyway and exit code will give more inforamtion */
    bool switch_user = (user->CachePrivate() || user->StrictSession());
    std::string cmd; 
    if(up) { cmd=nordugrid_libexec_loc()+"/uploader"; }
    else { cmd=nordugrid_libexec_loc()+"/downloader"; };
    uid_t user_id = user->get_uid();
    if(user_id == 0) user_id=i->get_uid();
    std::string user_id_s = Arc::tostring(user_id);
    std::string max_files_s;
    std::string min_speed_s;
    std::string min_speed_time_s;
    std::string min_average_speed_s;
    std::string max_inactivity_time_s;
    int argn=4;
    const char* args[] = {
      cmd.c_str(),
      "-U",
      user_id_s.c_str(),
      "-f",
      NULL, // -n
      NULL, // (-n)
      NULL, // -c
      NULL, // -p
      NULL, // -l
      NULL, // -s
      NULL, // (-s)
      NULL, // -S
      NULL, // (-S)
      NULL, // -a
      NULL, // (-a)
      NULL, // -i
      NULL, // (-i)
      NULL, // -d
      NULL, // (-d)
      NULL, // -C
      NULL, // (-C)
      NULL, // id
      NULL, // control
      NULL, // session
      NULL,
      NULL
    };
    if(JobsList::max_downloads > 0) {
      max_files_s=Arc::tostring(JobsList::max_downloads);
      args[argn]="-n"; argn++;
      args[argn]=(char*)(max_files_s.c_str()); argn++;
    };
    if(!use_secure_transfer) { 
      args[argn]="-c"; argn++;
    };
    if(use_passive_transfer) { 
      args[argn]="-p"; argn++;
    };
    if(use_local_transfer) { 
      args[argn]="-l"; argn++;
    };
    if(JobsList::min_speed) {
      min_speed_s=Arc::tostring(JobsList::min_speed);
      min_speed_time_s=Arc::tostring(JobsList::min_speed_time);
      args[argn]="-s"; argn++; 
      args[argn]=(char*)(min_speed_s.c_str()); argn++;
      args[argn]="-S"; argn++; 
      args[argn]=(char*)(min_speed_time_s.c_str()); argn++;
    };
    if(JobsList::min_average_speed) {
      min_average_speed_s=Arc::tostring(JobsList::min_average_speed);
      args[argn]="-a"; argn++; 
      args[argn]=(char*)(min_average_speed_s.c_str()); argn++;
    };
    if(JobsList::max_inactivity_time) {
      max_inactivity_time_s=Arc::tostring(JobsList::max_inactivity_time);
      args[argn]="-i"; argn++; 
      args[argn]=(char*)(max_inactivity_time_s.c_str()); argn++;
    };
    std::string debug_level = Arc::level_to_string(Arc::Logger::getRootLogger().getThreshold());
    std::string cfg_path = nordugrid_config_loc();
    if (!debug_level.empty()) {
      args[argn]="-d"; argn++;
      args[argn]=(char*)(debug_level.c_str()); argn++;
    }
    if (!nordugrid_config_loc().empty()) {
      args[argn]="-C"; argn++;
      args[argn]=(char*)(cfg_path.c_str()); argn++;
    }
    args[argn]=(char*)(i->job_id.c_str()); argn++;
    args[argn]=(char*)(user->ControlDir().c_str()); argn++;
    args[argn]=(char*)(i->SessionDir().c_str()); argn++;

    if(!up) { logger.msg(Arc::INFO,"%s: State PREPARING: starting child: %s",i->job_id,args[0]); }
    else { logger.msg(Arc::INFO,"%s: State FINISHING: starting child: %s",i->job_id,args[0]); };
    job_errors_mark_put(*i,*user);
    job_restart_mark_remove(i->job_id,*user);
    if(!RunParallel::run(*user,*i,(char**)args,&(i->child),switch_user)) {
      logger.msg(Arc::ERROR,"%s: Failed to run down/uploader process",i->job_id);
      if(up) {
        i->AddFailure("Failed to run uploader (post-processing)");
      } else {
        i->AddFailure("Failed to run downloader (pre-processing)");
      };
      return false;
    };
  } else {
    if(i->child->Running()) {
      logger.msg(Arc::VERBOSE,"%s: State: PREPARING/FINISHING: child is running",i->job_id);
      /* child is running - come later */
      return true;
    };
    /* child was run - check exit code */
    if(!up) { logger.msg(Arc::INFO,"%s: State: PREPARING: child exited with code: %i",i->job_id,i->child->Result()); }
    else { logger.msg(Arc::INFO,"%s: State: FINISHING: child exited with code: %i",i->job_id,i->child->Result()); };
    if(i->child->Result() != 0) { 
      if(i->child->Result() == 1) { 
        /* unrecoverable failure detected - all we can do is to kill the job */
        if(up) {
          logger.msg(Arc::ERROR,"%s: State: FINISHING: unrecoverable error detected (exit code 1)",i->job_id);
          i->AddFailure("Failed in files upload (post-processing)");
        } else {
          logger.msg(Arc::ERROR,"%s: State: PREPARING: unrecoverable error detected (exit code 1)",i->job_id);
          i->AddFailure("Failed in files download (pre-processing)");
        };
      } else if(i->child->Result() == 3) {
        /* in case of expired credentials there is a chance to get them 
           from credentials server - so far myproxy only */
#ifdef HAVE_MYPROXY_H
        if(GetLocalDescription(i)) {
          i->AddFailure("Internal error");
          if(i->local->credentialserver.length()) {
            std::string new_proxy_file =
                    user->ControlDir()+"/job."+i->job_id+".proxy.tmp";
            std::string old_proxy_file =
                    user->ControlDir()+"/job."+i->job_id+".proxy";
            remove(new_proxy_file.c_str());
            int h = open(new_proxy_file.c_str(),
                    O_WRONLY | O_CREAT | O_EXCL,S_IRUSR | S_IWUSR);
            if(h!=-1) {
              close(h);
              if(myproxy_renew(old_proxy_file.c_str(),new_proxy_file.c_str(),
                      i->local->credentialserver.c_str())) {
                renew_proxy(old_proxy_file.c_str(),new_proxy_file.c_str());
                /* imitate rerun request */
                job_restart_mark_put(*i,*user);
              };
            };
          };
        };
#endif
        if(up) {
          logger.msg(Arc::ERROR,"%s: State: FINISHING: credentials probably expired (exit code 3)",i->job_id);
          i->AddFailure("Failed in files upload due to expired credentials - try to renew");
        } else {
          logger.msg(Arc::ERROR,"%s: State: PREPARING: credentials probably expired (exit code 3)",i->job_id);
          i->AddFailure("Failed in files download due to expired credentials - try to renew");
        };
      } else if(i->child->Result() == 4) { // retryable cache error
        logger.msg(Arc::DEBUG, "%s: State: PREPARING/FINISHING: retryable error", i->job_id);
        delete i->child; i->child=NULL;
        retry = true;
        return true;
      } 
      else {
        if(up) {
          logger.msg(Arc::ERROR,"%s: State: FINISHING: some error detected (exit code %i). Recover from such type of errors is not supported yet.",i->job_id,i->child->Result());
          i->AddFailure("Failed in files upload (post-processing)");
        } else {
          logger.msg(Arc::ERROR,"%s: State: PREPARING: some error detected (exit code %i). Recover from such type of errors is not supported yet.",i->job_id,i->child->Result());
          i->AddFailure("Failed in files download (pre-processing)");
        };
      };
      delete i->child; i->child=NULL;
      if(up) {
        JobFailStateRemember(i,JOB_STATE_FINISHING);
      } else {
        JobFailStateRemember(i,JOB_STATE_PREPARING);
      };
      return false;
    };
    /* success code - move to next state */
    state_changed=true;
    delete i->child; i->child=NULL;
  };
  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool JobsList::state_submitting ( const iterator i,
bool &  state_changed,
bool  cancel = false 
) [private]

Definition at line 401 of file states.cpp.

                                                                                         {
  if(i->child == NULL) {
    /* no child was running yet, or recovering from fault */
    /* write grami file for globus-script-X-submit */
    JobLocalDescription* job_desc;
    if(i->local) { job_desc=i->local; }
    else {
      job_desc=new JobLocalDescription;
      if(!job_local_read_file(i->job_id,*user,*job_desc)) {
        logger.msg(Arc::ERROR,"%s: Failed reading local information",i->job_id);
        if(!cancel) i->AddFailure("Internal error: can't read local file");
        delete job_desc;
        return false;
      };
      i->local=job_desc;
    };
    if(!cancel) {  /* in case of cancel all preparations are already done */
      const char *local_transfer_s = NULL;
      if(use_local_transfer) { 
        local_transfer_s="joboption_localtransfer=yes";
      };
      if(!write_grami(*i,*user,local_transfer_s)) {
        logger.msg(Arc::ERROR,"%s: Failed creating grami file",i->job_id);
        return false;
      };
      if(!set_execs(*i,*user,i->SessionDir())) {
        logger.msg(Arc::ERROR,"%s: Failed setting executable permissions",i->job_id);
        return false;
      };
      /* precreate file to store diagnostics from lrms */
      job_diagnostics_mark_put(*i,*user);
      job_lrmsoutput_mark_put(*i,*user);
    };
    /* submit/cancel job to LRMS using submit/cancel-X-job */
    std::string cmd;
    if(cancel) { cmd=nordugrid_libexec_loc()+"/cancel-"+job_desc->lrms+"-job"; }
    else { cmd=nordugrid_libexec_loc()+"/submit-"+job_desc->lrms+"-job"; };
    if(!cancel) {
      logger.msg(Arc::INFO,"%s: state SUBMITTING: starting child: %s",i->job_id,cmd);
    } else {
      if(!job_lrms_mark_check(i->job_id,*user)) {
        logger.msg(Arc::INFO,"%s: state CANCELING: starting child: %s",i->job_id,cmd);
      } else {
        logger.msg(Arc::INFO,"%s: Job has completed already. No action taken to cancel",i->job_id);
        state_changed=true;
        return true;
      }
    };
    std::string grami = user->ControlDir()+"/job."+(*i).job_id+".grami";
    std::string cfg_path = nordugrid_config_loc();
    char const * args[5] ={ cmd.c_str(), "--config", cfg_path.c_str(), grami.c_str(), NULL };
    job_errors_mark_put(*i,*user);
    if(!RunParallel::run(*user,*i,args,&(i->child))) {
      if(!cancel) {
        i->AddFailure("Failed initiating job submission to LRMS");
        logger.msg(Arc::ERROR,"%s: Failed running submission process",i->job_id);
      } else {
        logger.msg(Arc::ERROR,"%s: Failed running cancel process",i->job_id);
      };
      return false;
    };
    return true;
  }
  else {
    /* child was run - check exit code */
    if(i->child->Running()) {
      /* child is running - come later */
      return true;
    };
    if(!cancel) {
      logger.msg(Arc::INFO,"%s: state SUBMITTING: child exited with code %i",i->job_id,i->child->Result());
    } else {
      logger.msg(Arc::INFO,"%s: state CANCELING: child exited with code %i",i->job_id,i->child->Result());
    };
    if(i->child->Result() != 0) { 
      if(!cancel) {
        logger.msg(Arc::ERROR,"%s: Job submission to LRMS failed",i->job_id);
        JobFailStateRemember(i,JOB_STATE_SUBMITTING);
      } else {
        logger.msg(Arc::ERROR,"%s: Failed to cancel running job",i->job_id);
      };
      delete i->child; i->child=NULL;
      if(!cancel) i->AddFailure("Job submission to LRMS failed");
      return false;
    };
    if(!cancel) {
      delete i->child; i->child=NULL;
      /* success code - get LRMS job id */
      std::string local_id=read_grami(i->job_id,*user);
      if(local_id.length() == 0) {
        logger.msg(Arc::ERROR,"%s: Failed obtaining lrms id",i->job_id);
        i->AddFailure("Failed extracting LRMS ID due to some internal error");
        JobFailStateRemember(i,JOB_STATE_SUBMITTING);
        return false;
      };
      /* put id into local information file */
      if(!GetLocalDescription(i)) {
        i->AddFailure("Internal error");
        return false;
      };   
      /*
      JobLocalDescription *job_desc;
      if(i->local) { job_desc=i->local; }
      else { job_desc=new JobLocalDescription; };
      if(i->local == NULL) {
        if(!job_local_read_file(i->job_id,*user,*job_desc)) {
          logger.msg(Arc::ERROR,"%s: Failed reading local information",i->job_id);
          i->AddFailure("Internal error");
          delete job_desc; return false;
        };
        i->local=job_desc;
      };
      */
      i->local->localid=local_id;
      if(!job_local_write_file(*i,*user,*(i->local))) {
        i->AddFailure("Internal error");
        logger.msg(Arc::ERROR,"%s: Failed writing local information",i->job_id);
        return false;
      };
    } else {
      /* job diagnostics collection done in backgroud (scan-*-job script) */
      if(!job_lrms_mark_check(i->job_id,*user)) {
        /* job diag not yet collected - come later */
        return true;
      } else {
        logger.msg(Arc::INFO,"%s: state CANCELING: job diagnostics collected",i->job_id);
        delete i->child; i->child=NULL;
        job_diagnostics_mark_move(*i,*user);
      };
    };
    /* move to next state */
    state_changed=true;
    return true;
  };
}

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned int JobsList::WakeupPeriod ( void  ) [inline, static]

Definition at line 141 of file states.h.

{ return wakeup_period; };

Here is the caller graph for this function:


Member Data Documentation

std::map<std::string, int> JobsList::finishing_job_share [private]

Definition at line 71 of file states.h.

std::map<std::string, int> JobsList::finishing_max_share [private]

Definition at line 74 of file states.h.

std::list<JobDescription> JobsList::jobs [private]

Definition at line 66 of file states.h.

int JobsList::jobs_num = { 0, 0, 0, 0, 0, 0, 0, 0, 0 } [static, private]

Definition at line 47 of file states.h.

int JobsList::jobs_pending = 0 [static, private]

Definition at line 48 of file states.h.

std::map< std::string, int > JobsList::limited_share [static, private]

Definition at line 68 of file states.h.

int JobsList::max_downloads = -1 [static, private]

Definition at line 60 of file states.h.

time_t JobsList::max_inactivity_time = 300 [static, private]

Definition at line 59 of file states.h.

int JobsList::max_jobs = -1 [static, private]

Definition at line 53 of file states.h.

Definition at line 51 of file states.h.

int JobsList::max_jobs_processing_emergency = 1 [static, private]

Definition at line 52 of file states.h.

int JobsList::max_jobs_running = -1 [static, private]

Definition at line 50 of file states.h.

unsigned int JobsList::max_processing_share = 0 [static, private]

Definition at line 54 of file states.h.

int JobsList::max_retries = DEFAULT_MAX_RETRIES [static, private]

Definition at line 61 of file states.h.

unsigned long long int JobsList::min_average_speed = 0 [static, private]

Definition at line 58 of file states.h.

unsigned long long int JobsList::min_speed = 0 [static, private]

Definition at line 56 of file states.h.

time_t JobsList::min_speed_time = 300 [static, private]

Definition at line 57 of file states.h.

Definition at line 76 of file states.h.

std::map<std::string, int> JobsList::preparing_job_share [private]

Definition at line 70 of file states.h.

std::map<std::string, int> JobsList::preparing_max_share [private]

Definition at line 73 of file states.h.

std::string JobsList::share_type = "" [static, private]

Definition at line 55 of file states.h.

bool JobsList::use_local_transfer = false [static, private]

Definition at line 64 of file states.h.

bool JobsList::use_passive_transfer = false [static, private]

Definition at line 63 of file states.h.

bool JobsList::use_secure_transfer = false [static, private]

Definition at line 62 of file states.h.

JobUser* JobsList::user [private]

Definition at line 75 of file states.h.

unsigned int JobsList::wakeup_period = 120 [static, private]

Definition at line 65 of file states.h.


The documentation for this class was generated from the following files: