From 02bd2c24b72b91eb3317d846d28669d8b6f595d9 Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Thu, 23 Feb 2023 09:47:47 +0100 Subject: [PATCH] feat(job-queue): deesigning methods --- include/vieter_job_queue.h | 73 +++++++++++++++++++++++++++++++++----- src/job-queue/README.md | 27 ++++++++++++++ 2 files changed, 91 insertions(+), 9 deletions(-) create mode 100644 src/job-queue/README.md diff --git a/include/vieter_job_queue.h b/include/vieter_job_queue.h index fc02d7e..aeb7e1e 100644 --- a/include/vieter_job_queue.h +++ b/include/vieter_job_queue.h @@ -14,27 +14,82 @@ typedef enum vieter_job_state { vieter_job_state_queued = 0, vieter_job_state_ready = 1, - vieter_job_state_build_finished = 2 + vieter_job_state_build_finished = 2, + vieter_job_state_failed = 3 } vieter_job_state; // This macro should be kept in sync with the above enum -#define VIETER_JOB_STATES 3 +#define VIETER_JOB_STATES 4 +/* + * Struct storing a report for why a certain job failed to be processed in the + * given state. + */ +typedef struct vieter_job_failure_report { + vieter_job_state failed_state; + char *msg; +} vieter_job_failure_report; + +vieter_job_failure_report *vieter_job_failure_report_init(); + +void vieter_job_failure_report_free(vieter_job_failure_report **ptp); + +/* + * Represents a job currently being processed in the system. A job migrates + * between different states before finally being removed from the queue. + */ typedef struct vieter_job { - int id; + uint64_t id; uint64_t next_scheduled_time; - vieter_cron_expression *ce; - bool single; - vieter_job_state state; - uint64_t state_transition_times[VIETER_JOB_STATES]; - bool dispatched; + vieter_cron_expression *schedule; void *build_config; + vieter_job_failure_report *failure_report; + uint64_t state_transition_times[VIETER_JOB_STATES]; + vieter_job_state current_state; + bool single; + bool dispatched; } vieter_job; +/* + * Allocate a new vieter_job object. + */ +vieter_job *vieter_job_init(); + +void vieter_job_free(vieter_job **ptp); + +/* + * Represents the actual queue managing the list of jobs. + */ typedef struct vieter_job_queue vieter_job_queue; +typedef enum vieter_job_queue_error { + vieter_job_queue_ok = 0, + vieter_job_queue_not_found = 1 +} vieter_job_queue_error; + +/* + * Allocate and initialize a new job queue. + */ vieter_job_queue *vieter_job_queue_init(); -void vieter_job_queue_insert(int id); +void vieter_job_queue_free(vieter_job_queue **ptp); + +/* + * Insert the given job into the system. + */ +vieter_job_queue_error vieter_job_queue_insert(vieter_job *job); + +/* + * Dispatch the job with the given id, returning the pointer to the job. + * Dispatching a job removes it from its respective state's queue. + */ +vieter_job_queue_error vieter_job_queue_dispatch(vieter_job **out, uint64_t id); + +/* + * Transition the job with the given id to the new state. This sets the + * job's dispatch flag to false, and adds it to the new state's queue. + */ +vieter_job_queue_error vieter_job_queue_transition(uint64_t id, + vieter_job_state new_state); #endif diff --git a/src/job-queue/README.md b/src/job-queue/README.md new file mode 100644 index 0000000..8fa9c94 --- /dev/null +++ b/src/job-queue/README.md @@ -0,0 +1,27 @@ +The goal of this job queue design is to process jobs in order, with each job +moving through a pipeline of tasks that need to be completed. + +At any given time, a job is in one of a few given states, e.g. "queued". These +states are explained below. Along with this, each job also has a "dispatched" +flag. If this flag is set to true, it means this job is currently being +processed. "Being processed" could mean anything; it depends entirely on the +state a job's in. While a job is dispatched, it is no longer present in the +priority queue of its respective state. + +## Job + +A job describes a scheduled build as it moves through the pipeline of states. +The job queue datastructure keeps track of all jobs in a central red-black +binary tree. For each state, a priority queue tracks in what order jobs should +be processed. + +## States + +* `queued`: a job that's in the job queue but does not yet need to be executed + (as defined by its timestamp) +* `ready`: a job that's scheduled for building, with all preprocessing tasks + fulfilled. +* `build_finished`: a job whose build has finished, and is waiting for any + post-build tasks. +* `failed`: a job whose processing failed at some point. Jobs in this state + include a failure report that describes in what state they failed, and why.