fix(lib): thread from_host through the wire format and the job-submit interning object (bug-1676, gitea #44)
- src/schema/controller.capnp: JobSubmitData gains
fromHost @10: Text $C.mapname("from_host") -- auto-regenerates
controller.capnp.c/h via the existing meson capnpc-c custom_target.
- src/include/xce/types.h: job_submit_data_t gains char* from_host.
- src/lib/jobj.c: jobsub_init/jobsub_destroy (the hand-written,
ref-counted, content-deduped job-submit interning object -- not
auto-generated) thread from_host through the deep-copy, the dedup
identity comparison, and the destroy path.
Closes the wire-format half of the round-trip: from_host now survives
from the apiserver's submission all the way through the controller and
back on every subsequent job-state push, and rides along for free in
the existing WAL_JOB_SUBMIT persistence across a controller restart.
Did not need to touch job.c's build_job_submit_payloads() (bare
pointer borrow of the already-decoded submit struct) or any WAL
apply-path code (capnp_encode_job/decode_Job already generically
handle the whole xce_job_t including its full .submit sub-struct).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AgYRU3zDTqNGV5Jk8aiKLg
This commit is contained in:
parent
fe8818b19b
commit
363709b032
4 changed files with 65 additions and 6 deletions
|
|
@ -333,6 +333,7 @@ typedef struct {
|
|||
char* user_group;
|
||||
char* job_description;
|
||||
char* resreq;
|
||||
char* from_host;
|
||||
} job_submit_data_t;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ static int jobsub_init(meta_obj_t* obj, va_list ap)
|
|||
dst->user_group = makeString(src->user_group);
|
||||
dst->job_description = makeString(src->job_description);
|
||||
dst->resreq = makeString(src->resreq);
|
||||
dst->from_host = makeString(src->from_host);
|
||||
|
||||
if (!(EQUAL_STRING(dst->queue, src->queue)
|
||||
&& EQUAL_STRING(dst->user, src->user)
|
||||
|
|
@ -155,7 +156,8 @@ static int jobsub_init(meta_obj_t* obj, va_list ap)
|
|||
&& EQUAL_STRING(dst->project_name, src->project_name)
|
||||
&& EQUAL_STRING(dst->user_group, src->user_group)
|
||||
&& EQUAL_STRING(dst->job_description, src->job_description)
|
||||
&& EQUAL_STRING(dst->resreq, src->resreq))) {
|
||||
&& EQUAL_STRING(dst->resreq, src->resreq)
|
||||
&& EQUAL_STRING(dst->from_host, src->from_host))) {
|
||||
jobsub_destroy(obj);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
@ -177,6 +179,7 @@ static void jobsub_destroy(meta_obj_t* obj)
|
|||
dereference(jobsub->user_group);
|
||||
dereference(jobsub->job_description);
|
||||
dereference(jobsub->resreq);
|
||||
dereference(jobsub->from_host);
|
||||
if (jobsub->start_info != NULL) {
|
||||
dereference(jobsub->start_info);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,7 +110,8 @@ static void test_jobsub_create(void)
|
|||
.project_name = "default",
|
||||
.user_group = NULL,
|
||||
.job_description = "no description",
|
||||
.resreq = "type == any" };
|
||||
.resreq = "type == any",
|
||||
.from_host = "review-client" };
|
||||
job_submit_data_t* s2 = NULL;
|
||||
|
||||
rc = xstring_table_init(32);
|
||||
|
|
@ -137,7 +138,9 @@ static void test_jobsub_create(void)
|
|||
&& EQUAL_STRING(s2->job_name, "J1")
|
||||
&& EQUAL_STRING(s2->project_name, "default")
|
||||
&& EQUAL_STRING(s2->job_description, "no description")
|
||||
&& EQUAL_STRING(s2->resreq, "type == any") && (s2->mintasks == 1)
|
||||
&& EQUAL_STRING(s2->resreq, "type == any")
|
||||
&& EQUAL_STRING(s2->from_host, "review-client")
|
||||
&& (s2->mintasks == 1)
|
||||
&& (s2->maxtasks == 5) && (s2->user_group == NULL));
|
||||
|
||||
job_obj_fini();
|
||||
|
|
@ -165,7 +168,8 @@ static void test_jobsub_share(void)
|
|||
.project_name = "default",
|
||||
.user_group = NULL,
|
||||
.job_description = "no description",
|
||||
.resreq = "type == any" };
|
||||
.resreq = "type == any",
|
||||
.from_host = "review-client" };
|
||||
job_submit_data_t* s2 = NULL;
|
||||
job_submit_data_t* s3 = NULL;
|
||||
|
||||
|
|
@ -193,7 +197,9 @@ static void test_jobsub_share(void)
|
|||
&& EQUAL_STRING(s2->job_name, "J1")
|
||||
&& EQUAL_STRING(s2->project_name, "default")
|
||||
&& EQUAL_STRING(s2->job_description, "no description")
|
||||
&& EQUAL_STRING(s2->resreq, "type == any") && (s2->mintasks == 1)
|
||||
&& EQUAL_STRING(s2->resreq, "type == any")
|
||||
&& EQUAL_STRING(s2->from_host, "review-client")
|
||||
&& (s2->mintasks == 1)
|
||||
&& (s2->maxtasks == 5) && (s2->user_group == NULL));
|
||||
|
||||
s3 = makeJobsub(&jobsub1);
|
||||
|
|
@ -204,6 +210,51 @@ static void test_jobsub_share(void)
|
|||
xstring_table_fini();
|
||||
}
|
||||
|
||||
/* bug-1676: from_host must participate in makeJobsub's content-dedup
|
||||
* identity, not just be silently dropped or ignored -- two submissions
|
||||
* differing ONLY in from_host must NOT collapse to the same interned
|
||||
* object (they are genuinely different submissions from different
|
||||
* clients), while an identical from_host still dedupes like every other
|
||||
* field (test_jobsub_share above). */
|
||||
static void test_jobsub_from_host_distinguishes_identity(void)
|
||||
{
|
||||
int rc;
|
||||
job_submit_data_t jobsub_a = { .queue = "xce",
|
||||
.user = "rshen",
|
||||
.mintasks = 1,
|
||||
.maxtasks = 5,
|
||||
.job_name = "J1",
|
||||
.resreq = "type == any",
|
||||
.from_host = "client-a" };
|
||||
job_submit_data_t jobsub_b = { .queue = "xce",
|
||||
.user = "rshen",
|
||||
.mintasks = 1,
|
||||
.maxtasks = 5,
|
||||
.job_name = "J1",
|
||||
.resreq = "type == any",
|
||||
.from_host = "client-b" };
|
||||
job_submit_data_t* sa = NULL;
|
||||
job_submit_data_t* sb = NULL;
|
||||
|
||||
rc = xstring_table_init(32);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
rc = job_obj_init(31, 31);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
sa = makeJobsub(&jobsub_a);
|
||||
sb = makeJobsub(&jobsub_b);
|
||||
|
||||
TEST_ASSERT_TRUE(sa != NULL);
|
||||
TEST_ASSERT_TRUE(sb != NULL);
|
||||
TEST_ASSERT_TRUE(sa != sb);
|
||||
TEST_ASSERT_TRUE(EQUAL_STRING(sa->from_host, "client-a"));
|
||||
TEST_ASSERT_TRUE(EQUAL_STRING(sb->from_host, "client-b"));
|
||||
|
||||
job_obj_fini();
|
||||
xstring_table_fini();
|
||||
}
|
||||
|
||||
static void test_job_create(void)
|
||||
{
|
||||
int rc;
|
||||
|
|
@ -230,7 +281,8 @@ static void test_job_create(void)
|
|||
.project_name = "default",
|
||||
.user_group = NULL,
|
||||
.job_description = "no description",
|
||||
.resreq = "type == any" };
|
||||
.resreq = "type == any",
|
||||
.from_host = "review-client" };
|
||||
xce_job_t job1 = { .submit = &jobsub1 };
|
||||
job_t* j2 = NULL;
|
||||
time_t now = time(NULL);
|
||||
|
|
@ -278,6 +330,7 @@ static void test_job_create(void)
|
|||
&& EQUAL_STRING(j2->job.submit->project_name, "default")
|
||||
&& EQUAL_STRING(j2->job.submit->job_description, "no description")
|
||||
&& EQUAL_STRING(j2->job.submit->resreq, "type == any")
|
||||
&& EQUAL_STRING(j2->job.submit->from_host, "review-client")
|
||||
&& (j2->job.submit->mintasks == 1) && (j2->job.submit->maxtasks == 5)
|
||||
&& (j2->job.submit->user_group == NULL));
|
||||
|
||||
|
|
@ -295,5 +348,6 @@ void test_jobobj(void)
|
|||
RUN_TEST(test_startinfo_share);
|
||||
RUN_TEST(test_jobsub_create);
|
||||
RUN_TEST(test_jobsub_share);
|
||||
RUN_TEST(test_jobsub_from_host_distinguishes_identity);
|
||||
RUN_TEST(test_job_create);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -531,6 +531,7 @@ struct JobSubmitData $C.mapname("job_submit_data_t") {
|
|||
description @7: Text $C.mapname("job_description");
|
||||
resreq @8: Text;
|
||||
startinfo @9: JobStartInfo $C.mapname("start_info");
|
||||
fromHost @10: Text $C.mapname("from_host");
|
||||
}
|
||||
|
||||
struct JobSubmit $C.mapname("xce_job_submit_t") {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue