Changeset - 1774ee56e4a6
[Not reviewed]
default
0 1 0
LordOfWar - 16 years ago 2009-10-15 22:07:39

implemented timestamp into to job_list.xml to optimize the webpage
1 file changed with 11 insertions and 2 deletions:
0 comments (0 inline, 0 general)
src/server/distrend.c
Show inline comments
 
@@ -46,48 +46,49 @@
 
#include <libxml/tree.h>
 
#include <libxml/encoding.h>
 
#include <libxml/xmlwriter.h>
 
#include <libxml/xmlreader.h>
 

	
 
/* ******************* Structs ************************ */
 

	
 
// Gets config info from confs
 
struct distrend_config
 
{
 
  cfg_t *mycfg;
 
  struct options_common *options;
 
  struct distrend_listen **listens; /*< Null terminated array of structs */
 
  char *datadir;
 
};
 

	
 
struct general_info {
 
  short int jobs_in_queue; //
 
  unsigned short int free_clients;
 
  unsigned short int rendering_clients;//
 
  unsigned short int total_finished_jobs; //
 
  unsigned int total_frames_rendered; //
 
  unsigned int highest_jobnum;
 
  short int hibernate;
 
  unsigned int timestamp;
 
} general_info;
 

	
 

	
 

	
 
/*
 
  internally defined funcs's prototypes @TODO: Make all functions nice and proper */
 
void distrenjob_remove(struct distrenjob *head, struct distrenjob *bj);
 

	
 
struct distrenjob *distrenjob_get(struct distrenjob *head, jobnum_t jobnum);
 
void distrenjob_enqueue(struct distrenjob *head, struct distrenjob *job);
 
void mortition(struct distrenjob *head, struct distrenjob *job);
 
int makeJobDataXML(struct distrenjob *job);
 
int updateJobListXML(struct distrenjob *head);
 
int createQueueFromXML(struct distrenjob *head);
 
int reCreateQueueFromXML(struct distrenjob *head, xmlDocPtr doc, xmlNodePtr current);
 
void updateGeneralInfo();
 
void importGeneralInfo();
 
int updateJobStatsXML(struct distrenjob *job);
 

	
 

	
 
/* Global Vars, eliminate these */
 
jobnum_t jobnum = 0; // The next job number to create in the queue
 
int hcfjob; // Highest consecutively finished job
 
int highest_jobnum; // The job number of the most recently created job, this is used when creating new jobs
 
@@ -142,48 +143,49 @@ void remotio_send_to_client()
 
{
 
	// I am futile!
 
}
 

	
 
/** Fill variables after crash / shutdown from XML dumps */
 
int start_data(struct distrenjob *head, char *datadir)
 
{
 
  struct stat buffer;
 
  if(stat("general_info.xml", &buffer) == 0){
 
    importGeneralInfo();
 

	
 
    fprintf(stderr,"Parsing XML files and restoring previous state...\n");
 
    createQueueFromXML(head);
 
    return 1;
 
  }
 
  else{
 
    fprintf(stderr,"Couldn't find XML dump, starting up fresh.\n");
 
    general_info.total_finished_jobs = 0;
 
    general_info.total_frames_rendered = 0;
 
    general_info.free_clients = 0;
 
    general_info.highest_jobnum = 0;
 
    general_info.jobs_in_queue = 0;
 
    general_info.rendering_clients = 0;
 
    general_info.hibernate = 0;
 
    general_info.timestamp = 0;
 

	
 
    // Create the stor directory
 
    // char *stor;
 
    // _distren_asprintf(&stor, "%s/stor", datadir);
 
    // mkdir(stor);
 
    return 2;
 
  }
 
}
 

	
 
/** Finish-Setter: Sets a frame to the "completed" status.*/
 
void finish_frame(struct distrenjob *head, struct distrenjob *distrenjob, int frame)
 
{
 
  distrenjob->frameset[frame].status = FRAMESETSTATUS_DONE;
 
  distrenjob->total_render_time = distrenjob->total_render_time + (clock() - distrenjob[jobnum].frameset[frame].start_time);
 
  distrenjob->completed_frames++;
 
  distrenjob->assigned_frames--;
 
  general_info.total_frames_rendered++; // Increase total frames var for stats
 

	
 
  updateGeneralInfo();
 
  updateJobStatsXML(distrenjob);
 
}
 

	
 
/** "mortition" check to see if a job is actually done by scanning the folder of the job to make sure all frames are present*/
 
void mortition(struct distrenjob *head, struct distrenjob *job)
 
@@ -572,48 +574,49 @@ void importGeneralInfo()
 
  xmlDocPtr doc;
 
  xmlNodePtr cur;
 

	
 
  doc = xmlParseFile("general_info.xml");
 
  cur = xmlDocGetRootElement(doc);
 
  if (xmlStrcmp(cur->name, (xmlChar*)"general_info"))
 
    {
 
      fprintf(stderr, "xml document is wrong type");
 
      xmlFreeDoc(doc);
 
      return;
 
    }
 

	
 
  cur = cur->xmlChildrenNode;
 
  general_info.jobs_in_queue = atoi((char*)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1));
 
  cur = cur->next;
 
  general_info.total_finished_jobs = atoi((char*)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1));
 
  cur = cur->next;
 
  general_info.total_frames_rendered = atoi((char*)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1));
 
  cur = cur->next;
 
  general_info.highest_jobnum = atoi((char*)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1));
 

	
 
  general_info.hibernate = 0;
 
  general_info.free_clients = 0;
 
  general_info.rendering_clients = 0;
 
  general_info.timestamp = 0;
 

	
 
  xmlFreeDoc(doc);
 
}
 

	
 
// returns 1 on successful completion of xml file
 
// creates the xml file that slaves read from, and is used to restart distren
 
int makeJobDataXML(struct distrenjob *job)
 
{
 
  xmlTextWriterPtr writer;
 
  char *tmp; // temporarily holds strings to be given to the xml writer
 

	
 
  _distren_asprintf(&tmp, "stor/job%d/job_info.xml", job->jobnum);
 

	
 
  // create xml document at the location tmp with no compression
 
  writer = xmlNewTextWriterFilename(tmp, 0);
 
  xmlTextWriterStartDocument(writer, NULL, "utf-8", NULL);
 

	
 
  // write distrenjob element and add its attributes
 
  xmlTextWriterStartElement(writer, (xmlChar*)"job");
 
  xmlTextWriterWriteAttribute(writer, (xmlChar*)"name", (xmlChar*)job->name);
 
  xmlTextWriterWriteAttribute(writer, (xmlChar*)"submitter", (xmlChar*)job->submitter);
 
  _distren_asprintf(&tmp, "%d", job->priority);
 
  xmlTextWriterWriteAttribute(writer, (xmlChar*)"priority", (xmlChar*)tmp);
 

	
 
@@ -725,56 +728,61 @@ int updateJobStatsXML(struct distrenjob 
 
	  xmlTextWriterWriteAttribute(writer, (xmlChar*)"assigned_frames", (xmlChar*)tmp);
 
	  _distren_asprintf(&tmp, "%d", job->completed_frames);
 
	  xmlTextWriterWriteAttribute(writer, (xmlChar*)"completed_frames", (xmlChar*)tmp);
 
	  _distren_asprintf(&tmp, "%d", job->total_render_time);
 
	  xmlTextWriterWriteAttribute(writer, (xmlChar*)"total_render_time", (xmlChar*)tmp);
 

	
 
	  // end document
 
	  xmlTextWriterEndDocument(writer);
 
	  // free writer and save xml file to disk
 
	  xmlFreeTextWriter(writer);
 

	
 
	  return 1;
 
}
 

	
 
// returns 1 if successful
 
// updates job_list.xml which lists all the jobs in the queue
 
int updateJobListXML(struct distrenjob *head)
 
{
 
  struct distrenjob *job;
 
  xmlTextWriterPtr writer;
 
  char *tmp;
 
  char *tmp2;
 
  int counter;
 

	
 
  // update timestamp
 
  general_info.timestamp++;
 
  if(general_info.timestamp > 65530)
 
		  general_info.timestamp = 0;
 

	
 
  writer = xmlNewTextWriterFilename("job_list.xml", 0);
 
  xmlTextWriterStartDocument(writer, NULL, "utf-8", NULL);
 

	
 
  // create root element job_list
 
  xmlTextWriterStartElement(writer, (xmlChar*)"job_list");
 

	
 
  _distren_asprintf(&tmp, "%d", general_info.jobs_in_queue);
 
  xmlTextWriterWriteAttribute(writer, (xmlChar*)"amount", (xmlChar*)tmp);
 
  _distren_asprintf(&tmp, "%d", general_info.timestamp);
 
  xmlTextWriterWriteAttribute(writer, (xmlChar*)"timestamp", (xmlChar*)tmp);
 

	
 
  counter = 0;
 
  for(job = head->next; job; job = job->next)
 
    {
 
      _distren_asprintf(&tmp, "jobnum%d", counter);
 
      _distren_asprintf(&tmp2, "%d", job->jobnum);
 
      xmlTextWriterWriteElement(writer, (xmlChar*)tmp, (xmlChar*)tmp2);
 
      counter++;
 
    }
 

	
 
  // close elements and end document
 
  xmlTextWriterEndDocument(writer);
 

	
 
  // free writer and save xml file to disk
 
  xmlFreeTextWriter(writer);
 
  return 1;
 
}
 

	
 
// returns 1 if completed successfully, 0 if not
 
// this reads a list of jobs in the queue before DistRen was shut down
 
// and then adds the jobs to the queue, as if it were never shut down
 
int createQueueFromXML(struct distrenjob *head)
 
{
 
  xmlDocPtr doc;  // holds xml document in memory
 
@@ -936,48 +944,49 @@ int main(int argc, char *argv[])
 

	
 

	
 
  struct distrenjob head;
 

	
 
  int cont;
 
  struct distrend_listenset *listenset;
 
  struct distrend_config *config;
 

	
 
  enum clientstatus
 
  {
 
    CLIENTSTATUS_UNINITIALIZED = 0,
 
    CLIENTSTATUS_BUSY = 1,
 
    CLIENTSTATUS_IDLE = 2
 
  } clientstatus;
 

	
 

	
 
  // initialize general_info struct, this should be done by start_data()
 
  general_info.jobs_in_queue = 0;
 
  general_info.free_clients = 0;
 
  general_info.rendering_clients = 0;
 
  general_info.total_finished_jobs = 0;
 
  general_info.total_frames_rendered = 0;
 
  general_info.highest_jobnum = 0;
 
  general_info.hibernate = 0;
 
  general_info.timestamp = 0;
 

	
 
  int command;
 
  jobnum_t jobnum;
 
  struct distrenjob *tmp_job;
 
  struct frameset *tmp_frame;
 
  int type;
 
  char *name;
 
  char *submitter;
 
  char *email;
 
  int priority;
 
  int width;
 
  int height;
 
  int start_frame;
 
  int end_frame;
 
  size_t read_buf;
 

	
 
  head.priority = 0; // make head have the highest priority
 

	
 
  xmlinit();
 

	
 
  test = 0;
 
  for(counter = 0; counter < argc; counter ++)
 
    {
 
      if(strcmp(argv[counter], "-h") == 0)
0 comments (0 inline, 0 general)