myxce/src/docs/p1-2-host-select.md
Rongsong Shen b38babb7d6 feat: implement Phase 4d const-fold transform for select AST
Adds sel_const_fold_pass() — a single-pass bottom-up const-fold that
runs after the Phase 4c flatten loop in parse_select():

  4d-1  EQ/NE with either operand SEL_ANY → SEL_TRUE / SEL_FALSE
        (checks both child slots — commutativity sort makes SEL_ANY
        position non-deterministic after makeSelectNode interning)
  4d-2  Identity laws: TRUE&&X→X, X&&TRUE→X, FALSE||X→X, X||FALSE→X
  4d-3  Annihilation laws: FALSE&&X→FALSE, TRUE||X→TRUE (symmetric)
  4d-4  Complement laws: !TRUE→FALSE, !FALSE→TRUE

Memory semantics:
  level==0 (API server): frees orphaned nodes via free_select_node /
    sel_free_tree; OOM from makeSelectNode returns original node safely
  level>0  (CSE/scheduler): never manually frees; annihilation folds
    return the already-interned left/right singleton directly (no
    redundant makeSelectNode call); OOM guard unconditional so CSE
    mode also degrades gracefully instead of returning NULL

9 new TDD tests added to test_select.c (RED→GREEN verified).
All 166 tests pass (157 prior + 9 Phase 4d).
2026-04-29 08:24:04 +00:00

3.3 KiB

P1-2: Host Resource Requirement Select — Investigation

Status

  • [>] Under investigation (moved from apiserver-backend-tasks.md)

Background

The select field in an LSF-style resource requirement string (e.g. select[mem>4096 && type==X86_64]) filters candidate hosts before slot allocation. Currently EvalSelectForHost is a no-CGO stub that always returns errNoCGO.

The full feature requires two layers:

  1. C parser + evaluator — parse the boolean select expression into an AST and evaluate it against a host's resource values.
  2. Go bridge — call the C evaluator via CGO and wire it into FilterHostByResReqSelect in the controllers layer.

Sub-tasks

#11 P1-2a: C select expression parser (PEG + eval)

Files to touch:

  • include/resreq.h — Replace empty xce_resreq_select_ stub with expression-tree types, enums, and extern declarations for parse_select, eval_select, free_select.
  • lib/xce_select.peg — New PEG grammar for select boolean expressions (right-recursive, handles &&, ||, !, comparison operators, numeric literals, string literals, resource names).
  • lib/resreq.c — Implement parse_select(), eval_select(), free_select(); update kill_primary_resreq() to call free_select().
  • lib/meson.build — Add xce_select.peg to explicit source list so the PEG tool generates C.
  • lib/testsuite/ — TDD tests for parse/eval before implementing.

Open questions:

  • Which PEG library is already available in the Nix/Meson build? (peg, lemon, re2c?)
  • Exact grammar for comparison operators — LSF allows mem > 4096, type == X86_64, swp >= 0. Need to confirm all supported operators and value types.
  • Does eval_select receive a flat key-value map of resource values, or a pointer to the full xce_host_t struct?
  • Error reporting strategy — return a bool+error-string, or a tri-state (true/false/parse-error)?

#12 P1-2b: Go EvalSelectForHost + FilterHostByResReqSelect (blocked by #11)

Files to touch:

  • backend/clib.go — Implement EvalSelectForHost(hostname, selectExpr string) error using cgo.Handle for callback context; add #include "resreq.h", extern C declarations, xce_select_destroy helper.
  • controllers/hosts.go — Implement FilterHostByResReqSelect(hosts []models.HostInfo, expr string), update preCheckHostRequest() limit from 4094 → 1024 bytes.

Open questions:

  • Does EvalSelectForHost need to look up live resource values from the in-memory store, or are values passed in directly by the C layer?
  • cgo.Handle usage pattern — confirm whether a per-call handle or a session-level handle is needed.
  • Input validation: max expression length (1024 bytes), allowed characters.

Investigation Checklist

  • Survey existing PEG tooling in the Meson/Nix build environment.
  • Read include/resreq.h current state to understand xce_resreq_select_ stub.
  • Trace how kill_primary_resreq() works today and where free_select() must be called.
  • Confirm resource value structure passed to eval_select.
  • Confirm LSF select grammar spec (operators, value types, nesting depth).
  • Prototype PEG grammar for a subset (numeric comparisons only) and get it compiling.
  • Decide error propagation strategy across the CGO boundary.
  • Write TDD tests for C parser before any implementation.