feat(scheduler-core): implement core event batch push interface (task 4.3)
Defines xce_core_event_type_t/xce_core_event_t (9 event kinds: config, job, worker, resource, resval full/delta, job state change, job update, queue update, job rusage) in core.h. Implements xce_core_push_events() in a new core_events.c (split out of core.c to stay under the 800-line cap): rejects -EBUSY mid-session, otherwise applies each event's core- state mutation and fires the corresponding picker hook synchronously, exactly once per event, before returning. CONFIG_PUSH decomposes the pushed config's embedded queues/resources/resvals via shared helpers (also reused by QUEUE_UPDATE's upsert path), mirroring the existing sched_init_config()/sched_init_resources()/sched_init_sharedInst()/ sched_init_queues(). Narrows sched_resolve_job_picker() to take xce_sched_core_t* (pure type change, zero behavior change). Purely additive — not wired into the live scheduling path yet (task 5.x). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019dw5WnN3DXStaEaPYfACU1
This commit is contained in:
parent
e9b5c3f589
commit
e6c0a2448a
10 changed files with 1613 additions and 43 deletions
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "dataq.h"
|
||||
#include "mylock.h"
|
||||
#include "plugin.h"
|
||||
#include "sched/types.h"
|
||||
#include "xce/types.h"
|
||||
#include "zarray.h"
|
||||
|
|
@ -114,4 +115,122 @@ extern int sched_add_project(xce_sched_core_t*, xce_sched_project_t*);
|
|||
extern int sched_job_is_ready(xce_sched_job_t*);
|
||||
extern int sched_queue_is_ready(xce_sched_queue_t*);
|
||||
|
||||
/*
|
||||
* sched_resolve_job_picker - Req 1 AC 6 / Req 2 AC 5 (scheduler-core spec,
|
||||
* task 2.4). Resolves core->job_pick_plugin against the plugin registry
|
||||
* (core->plugins, the same plugin_register()/key_find() mechanism every
|
||||
* other plugin category uses) and validates the result actually implements
|
||||
* the picker MUST hooks (xce_job_picker_iface_t: next_job, begin_session,
|
||||
* end_session, on_dispatch, on_pend). Returns 0 and sets *out on success; a
|
||||
* negative errno on failure:
|
||||
* -EINVAL bad arguments, or core->job_pick_plugin is unset (NULL), or
|
||||
* the name IS registered but is not a usable picker
|
||||
* -ENOENT the configured name is not registered at all
|
||||
* Implemented in schedobj.c. Declared here (task 4.3, scheduler-core spec)
|
||||
* -- moved from scheduler.h's xce_scheduler_t* signature to this
|
||||
* xce_sched_core_t* signature so xce_core_push_events() (core.c, below) can
|
||||
* call it directly without core.c depending on scheduler.h (forbidden --
|
||||
* see this header's own boundary comment). Every existing call site already
|
||||
* held an xce_scheduler_t* and now passes &sched->core instead; no
|
||||
* resolution logic is duplicated.
|
||||
*/
|
||||
extern int sched_resolve_job_picker(xce_sched_core_t*, xce_sched_plugin_t**);
|
||||
|
||||
/*
|
||||
* xce_core_event_type_t / xce_core_event_t - the core's typed input-event
|
||||
* representation (scheduler-core spec, task 4.3, Req 5 AC 4). Exactly the 9
|
||||
* event kinds task 4.3 scopes in: BEGIN_ROUND and END_SESSION belong to
|
||||
* task 4.4's session-start signal, deliberately not added here.
|
||||
*
|
||||
* Each event carries a timestamp (`ts`, nanoseconds since epoch) and a
|
||||
* type-specific payload (Req 5 AC 4's field tables). Six of the nine kinds
|
||||
* additionally drive a picker state-change hook (xce_core_push_events()'s
|
||||
* own doc comment, core.c, maps each type to its hook one-for-one);
|
||||
* WORKERS_PUSH/RESOURCES_PUSH/RESVALS_FULL/RESVALS_DELTA are state-update
|
||||
* only -- "picking is about job ordering, not resource availability"
|
||||
* (plugin.h's own Req 1 AC 2 comment).
|
||||
*/
|
||||
typedef enum {
|
||||
XCE_CORE_EVENT_CONFIG_PUSH = 1,
|
||||
XCE_CORE_EVENT_JOBS_PUSH,
|
||||
XCE_CORE_EVENT_WORKERS_PUSH,
|
||||
XCE_CORE_EVENT_RESOURCES_PUSH,
|
||||
XCE_CORE_EVENT_RESVALS_FULL,
|
||||
XCE_CORE_EVENT_RESVALS_DELTA,
|
||||
XCE_CORE_EVENT_JOB_STATE_CHANGE,
|
||||
XCE_CORE_EVENT_JOB_UPDATE,
|
||||
XCE_CORE_EVENT_QUEUE_UPDATE,
|
||||
XCE_CORE_EVENT_JOB_RUSAGE,
|
||||
} xce_core_event_type_t;
|
||||
|
||||
typedef struct {
|
||||
xce_core_event_type_t type;
|
||||
uint64_t ts; /* nanoseconds since epoch */
|
||||
union {
|
||||
struct {
|
||||
xce_conf4sched_t* config;
|
||||
} config_push;
|
||||
struct {
|
||||
int njobs;
|
||||
xce_job_t** jobs;
|
||||
} jobs_push;
|
||||
struct {
|
||||
int nworkers;
|
||||
xce_worker_t** workers;
|
||||
} workers_push;
|
||||
struct {
|
||||
int n;
|
||||
xce_resource_t** resources;
|
||||
} resources_push;
|
||||
struct {
|
||||
int n;
|
||||
xce_resval_t** resvals;
|
||||
} resvals_full;
|
||||
struct {
|
||||
xce_resval_list_t* deltas;
|
||||
} resvals_delta;
|
||||
struct {
|
||||
uint64_t jobid;
|
||||
uint32_t old_state;
|
||||
uint32_t new_state;
|
||||
int32_t exit_code;
|
||||
} job_state_change;
|
||||
struct {
|
||||
uint64_t jobid;
|
||||
uint32_t changed_fields;
|
||||
xce_job_t* job;
|
||||
} job_update;
|
||||
struct {
|
||||
xce_queue_t* queue;
|
||||
} queue_update;
|
||||
struct {
|
||||
uint64_t jobid;
|
||||
xce_job_rusages_t* rusages;
|
||||
} job_rusage;
|
||||
} u;
|
||||
} xce_core_event_t;
|
||||
|
||||
/*
|
||||
* xce_core_push_events - Req 5 AC 4 / AC 8 (scheduler-core spec, task 4.3;
|
||||
* design.md "Driver -> Core Protocol", "Core Interface Contract"). Batch-
|
||||
* pushes `nevents` events, applying each one's core-state mutation in
|
||||
* order and -- for the six event kinds that have one -- synchronously
|
||||
* calling the resolved picker's corresponding state-change hook exactly
|
||||
* once per event, in the calling (driver) thread, before this call
|
||||
* returns. See core.c for the full per-event-type contract and the
|
||||
* type-to-hook mapping.
|
||||
*
|
||||
* Only valid between scheduling sessions (core->session_active == 0):
|
||||
* this is what makes calling picker hooks synchronously, from the driver
|
||||
* thread, safe -- the picker thread is blocked on cbuf_get(&wbuf) and the
|
||||
* allocator thread on cbuf_get(&jbuf), so no session is concurrently
|
||||
* reading the state this call mutates. Returns -EBUSY (no event applied)
|
||||
* if a session is active; -EINVAL for bad arguments (core NULL, or events
|
||||
* NULL with nevents > 0). Per-event failures (e.g. JOB_UPDATE naming an
|
||||
* unknown jobid) are logged and do not abort the rest of the batch --
|
||||
* same discipline scheduler.c's existing sched_update() dataq loop
|
||||
* already follows.
|
||||
*/
|
||||
extern int xce_core_push_events(xce_sched_core_t*, xce_core_event_t*, int);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue