aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsinanmohd <sinan@sinanmohd.com>2024-06-14 20:27:10 +0530
committersinanmohd <sinan@sinanmohd.com>2024-06-14 20:42:14 +0530
commitf407bbb1b00194fdc89ca382f4cf2f1f536ab18e (patch)
tree1e69cc2d1360e950b9e85208352849038cfca2f6
parent58fe7d147774960e3fb7dbc53a3e5ecf106ebf01 (diff)
queue: recover from nix eval errors
-rw-r--r--include/jobs.h9
-rw-r--r--include/queue.h2
-rw-r--r--src/build.c7
-rw-r--r--src/jobs.c56
-rw-r--r--src/queue.c11
5 files changed, 53 insertions, 32 deletions
diff --git a/include/jobs.h b/include/jobs.h
index 1044eaa..3a1fb19 100644
--- a/include/jobs.h
+++ b/include/jobs.h
@@ -21,10 +21,17 @@ struct job {
CIRCLEQ_ENTRY(job) clist;
};
+typedef enum {
+ JOB_READ_SUCCESS = 0,
+ JOB_READ_EOF = 1,
+ JOB_READ_EVAL_ERR = 2,
+ JOB_READ_JSON_INVAL = 3,
+} job_read_state_t;
+int job_read(FILE *stream, struct job **jobs);
+
int jobs_init(FILE **stream);
int job_new(struct job **j, char *name, char *drv_path);
void job_free(struct job *j);
-int job_read(FILE *stream, struct job **jobs);
#define JOBS_H
#endif
diff --git a/include/queue.h b/include/queue.h
index 5f2d5f4..6608ec4 100644
--- a/include/queue.h
+++ b/include/queue.h
@@ -1,6 +1,6 @@
#include <pthread.h>
-#include <sys/queue.h>
#include <semaphore.h>
+#include <sys/queue.h>
#include "jobs.h"
diff --git a/src/build.c b/src/build.c
index d846217..98fc9d7 100644
--- a/src/build.c
+++ b/src/build.c
@@ -1,12 +1,12 @@
#include <errno.h>
-#include <stdbool.h>
#include <pthread.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "build.h"
-#include "queue.h"
#include "jobs.h"
+#include "queue.h"
#include "util.h"
static int build(struct queue *queue);
@@ -39,7 +39,8 @@ out:
pthread_exit(NULL);
}
-static int build(struct queue *queue) {
+static int build(struct queue *queue)
+{
struct job *job;
int ret = 0;
diff --git a/src/jobs.c b/src/jobs.c
index 0205c71..c6141e6 100644
--- a/src/jobs.c
+++ b/src/jobs.c
@@ -58,15 +58,14 @@ static int job_read_inputdrvs(struct job *job, cJSON *input_drvs)
}
ret = job_new(&dep_job, NULL, drv_path);
- if (ret < 0) {
- ret = -EPERM;
+ if (ret < 0)
goto out_free;
- }
cJSON_ArrayForEach (output, array) {
out_name = strdup(output->valuestring);
if (out_name == NULL) {
- ret = -EPERM;
+ print_err("%s", strerror(errno));
+ ret = -errno;
goto out_free;
}
@@ -135,68 +134,80 @@ int job_read(FILE *stream, struct job **job)
{
cJSON *temp;
- int ret = 0;
+ char *drv_path = NULL;
+ struct job *j = NULL;
cJSON *root = NULL;
char *name = NULL;
- char *drv_path = NULL;
+ int ret = 0;
ret = json_streaming_read(stream, &root);
if (ret < 0 || ret == -EOF)
- return ret;
+ return JOB_READ_EOF;
+
+ temp = cJSON_GetObjectItemCaseSensitive(root, "error");
+ if (cJSON_IsString(temp)) {
+ puts(temp->valuestring);
+ ret = JOB_READ_EVAL_ERR;
+ goto out_free;
+ }
temp = cJSON_GetObjectItemCaseSensitive(root, "name");
if (!cJSON_IsString(temp)) {
- ret = -EPERM;
+ ret = JOB_READ_JSON_INVAL;
goto out_free;
}
name = strdup(temp->valuestring);
if (name == NULL) {
- ret = -EPERM;
+ ret = -errno;
+ print_err("%s", strerror(errno));
goto out_free;
}
temp = cJSON_GetObjectItemCaseSensitive(root, "drvPath");
if (!cJSON_IsString(temp)) {
- ret = -EPERM;
+ free(name);
+ ret = JOB_READ_JSON_INVAL;
goto out_free;
}
drv_path = strdup(temp->valuestring);
if (drv_path == NULL) {
- ret = -EPERM;
+ free(name);
+ print_err("%s", strerror(errno));
+ ret = -errno;
goto out_free;
}
- ret = job_new(job, name, drv_path);
+ ret = job_new(&j, name, drv_path);
if (ret < 0)
goto out_free;
temp = cJSON_GetObjectItemCaseSensitive(root, "inputDrvs");
if (!cJSON_IsObject(temp)) {
- ret = -EPERM;
+ ret = JOB_READ_JSON_INVAL;
goto out_free;
}
- ret = job_read_inputdrvs(*job, temp->child);
+ ret = job_read_inputdrvs(j, temp->child);
if (ret < 0)
goto out_free;
temp = cJSON_GetObjectItemCaseSensitive(root, "outputs");
if (!cJSON_IsObject(temp)) {
- ret = -EPERM;
+ ret = JOB_READ_JSON_INVAL;
goto out_free;
}
- ret = job_read_outputs(*job, temp->child);
+ ret = job_read_outputs(j, temp->child);
if (ret < 0)
goto out_free;
out_free:
cJSON_Delete(root);
- if (ret < 0) {
+ if (ret != JOB_READ_SUCCESS)
+ job_free(j);
+ else
+ *job = j;
+ if (ret == JOB_READ_JSON_INVAL)
print_err("%s", "Invalid JSON");
- free(name);
- free(drv_path);
- }
-
return ret;
}
@@ -246,8 +257,7 @@ int jobs_init(FILE **stream)
/* TODO: proproperly handle args */
char *const args[] = {
"nix-eval-jobs",
- "--flake",
- "github:sinanmohd/evanix#packages.x86_64-linux",
+ "<nixpkgs>",
NULL,
};
diff --git a/src/queue.c b/src/queue.c
index 746750e..e1e41ec 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -18,17 +18,20 @@ void *queue_thread_entry(void *queue_thread)
while (true) {
ret = job_read(qt->stream, &job);
- if (ret == -EOF) {
+ if (ret == JOB_READ_EOF) {
qt->queue->state = Q_ITS_OVER;
sem_post(&qt->queue->sem);
ret = 0;
break;
- } else if (ret < 0) {
+ } else if (ret == JOB_READ_EVAL_ERR ||
+ ret == JOB_READ_JSON_INVAL) {
+ continue;
+ } else if (ret == JOB_READ_SUCCESS) {
+ queue_push(qt->queue, job);
+ } else {
break;
}
-
- queue_push(qt->queue, job);
}
pthread_exit(NULL);