Skip to content

feat(spider-tdl)!: Add support for an optional init hook run once when a TDL package is loaded. - #409

Merged
LinZhihao-723 merged 1 commit into
y-scope:mainfrom
LinZhihao-723:tdl-init
Jul 18, 2026
Merged

feat(spider-tdl)!: Add support for an optional init hook run once when a TDL package is loaded.#409
LinZhihao-723 merged 1 commit into
y-scope:mainfrom
LinZhihao-723:tdl-init

Conversation

@LinZhihao-723

@LinZhihao-723 LinZhihao-723 commented Jul 18, 2026

Copy link
Copy Markdown
Member

Description

This PR lets a TDL package author register an optional initialization function that the task executor runs once, when the package is loaded. The hook is meant for one-time package-level setup and takes no arguments, returning Result<(), TdlError>.

Registration macro (spider-tdl)

register_tdl_package! gains an optional init field, placed between package_name and tasks:

spider_tdl::register_tdl_package! {
    package_name: "complex",
    init: my_init_fn,   // optional; `fn() -> Result<(), TdlError>`
    tasks: [add, sub, mul, div],
}

The macro always emits a new extern "C" entry point, __spider_tdl_package_init, alongside the existing get_version / get_name / execute symbols. When init is omitted, the emitted function defaults to a no-op that returns Ok(()), so the executor can dispatch to the symbol uniformly without probing whether the author supplied a hook. The emitted function returns a TaskExecutionResult carrying an empty success buffer, or the msgpack-encoded TdlError when the hook fails.

Executor (spider-task-executor)

TdlPackage::load resolves __spider_tdl_package_init and, if present, calls it once during load. A returned error aborts the load and surfaces as the new ExecutorError::PackageInitError(TdlError). The lookup is tolerant: a package that does not export the symbol at all (e.g. one built against an older spider-tdl) is loaded without running any init, so existing packages continue to load unchanged.

Note

BREAKING CHANGE:
The TDL package FFI contract now defines a fourth entry point, __spider_tdl_package_init. Every package built with register_tdl_package! exports it, and any tooling or hand-rolled package that reproduces or enumerates the TDL entry-point set must account for it. The executor tolerates the symbol's absence, so packages built against the previous spider-tdl still load.

Checklist

  • The PR satisfies the contribution guidelines.
  • This is a breaking change and that has been indicated in the PR title, OR this isn't a
    breaking change.
  • Necessary docs have been updated, OR no docs need to be updated.

Validation performed

  • Ensure all workflows pass.
  • Add unit tests to assert basic init behavior.

Summary by CodeRabbit

  • New Features

    • TDL packages can now run an optional initialization hook once when loaded.
    • Package initialization failures are reported with a dedicated error.
    • Packages without an initialization hook continue to load normally.
  • Bug Fixes

    • Prevents tasks from running before required package initialization completes.
  • Tests

    • Added integration coverage for successful initialization and initialization failures.

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Adds optional TDL package initialization hooks. Registered packages export an init symbol, the executor runs it during loading, init errors become PackageInitError, and Huntsman integration tests validate successful initialization and failure propagation.

Changes

TDL package initialization

Layer / File(s) Summary
Package init symbol generation
components/spider-tdl/src/register.rs
register_tdl_package! accepts an optional init function, exports __spider_tdl_package_init, and supplies a tested no-op default.
Package init loading and error propagation
components/spider-task-executor/src/error.rs, components/spider-task-executor/src/manager.rs
TdlPackage::load optionally resolves and invokes the init symbol, decodes returned TdlError values, and reports PackageInitError.
Integration package and init tests
tests/huntsman/integration-test-tasks/src/lib.rs, tests/huntsman/tdl-integration/Cargo.toml, tests/huntsman/tdl-integration/tests/init.rs
The test package registers an initialization hook and assertion task; ignored integration tests cover successful initialization and requested init failure.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant TdlPackageManager
  participant TdlPackageLoad
  participant PackageInitSymbol
  participant PackageInitFunction
  TdlPackageManager->>TdlPackageLoad: load package
  TdlPackageLoad->>PackageInitSymbol: resolve optional init symbol
  PackageInitSymbol-->>TdlPackageLoad: init function or missing symbol
  TdlPackageLoad->>PackageInitFunction: invoke init once
  PackageInitFunction-->>TdlPackageLoad: success or encoded TdlError
  TdlPackageLoad-->>TdlPackageManager: loaded package or PackageInitError
Loading

Possibly related PRs

  • y-scope/spider#325: Also modifies ExecutorError, overlapping with this PR’s package initialization error variant.

Suggested reviewers: sitaowang1998

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: optional package init hook support when loading TDL packages.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@LinZhihao-723
LinZhihao-723 marked this pull request as ready for review July 18, 2026 04:18
@LinZhihao-723
LinZhihao-723 requested review from a team and sitaowang1998 as code owners July 18, 2026 04:18

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/huntsman/tdl-integration/tests/init.rs (1)

68-75: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider using a RAII drop guard to ensure the environment variable is cleaned up on panic.

If manager.load() unexpectedly succeeds, .expect_err() will panic before remove_var is executed. While you have documented that cargo nextest process isolation mitigates the fallout, implementing a standard drop guard makes the test intrinsically panic-safe regardless of the test runner being used.

🛠️ Proposed refactor for panic safety
     // The init hook failing with this var set is the behavior under test.
     unsafe { std::env::set_var(ENV_SPIDER_TEST_TDL_INIT_SHOULD_FAIL, "1") };
+
+    struct EnvGuard(&'static str);
+    impl Drop for EnvGuard {
+        fn drop(&mut self) {
+            unsafe { std::env::remove_var(self.0) };
+        }
+    }
+    let _guard = EnvGuard(ENV_SPIDER_TEST_TDL_INIT_SHOULD_FAIL);
+
     let path = package_path();
     let mut manager = TdlPackageManager::new();
     let err = manager
         .load(&path)
         .expect_err("load should fail when init errors");
-    // SAFETY: see above.
-    unsafe { std::env::remove_var(ENV_SPIDER_TEST_TDL_INIT_SHOULD_FAIL) };
     let ExecutorError::PackageInitError(TdlError::ExecutionError(msg)) = &err else {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/huntsman/tdl-integration/tests/init.rs` around lines 68 - 75, Make the
environment-variable setup in the test using
ENV_SPIDER_TEST_TDL_INIT_SHOULD_FAIL panic-safe by introducing a scoped RAII
drop guard that removes the variable during unwinding. Update the cleanup around
manager.load and expect_err so normal execution and panic paths both remove the
variable, while preserving the existing failure assertion.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/huntsman/tdl-integration/tests/init.rs`:
- Around line 68-75: Make the environment-variable setup in the test using
ENV_SPIDER_TEST_TDL_INIT_SHOULD_FAIL panic-safe by introducing a scoped RAII
drop guard that removes the variable during unwinding. Update the cleanup around
manager.load and expect_err so normal execution and panic paths both remove the
variable, while preserving the existing failure assertion.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 71bfc203-3bd3-4cee-a8ed-4743bc6be4a0

📥 Commits

Reviewing files that changed from the base of the PR and between 14af9bd and e05eac0.

📒 Files selected for processing (6)
  • components/spider-task-executor/src/error.rs
  • components/spider-task-executor/src/manager.rs
  • components/spider-tdl/src/register.rs
  • tests/huntsman/integration-test-tasks/src/lib.rs
  • tests/huntsman/tdl-integration/Cargo.toml
  • tests/huntsman/tdl-integration/tests/init.rs

@LinZhihao-723 LinZhihao-723 changed the title feat(spider-tdl)!: Support an optional init hook run once when a TDL package is loaded. feat(spider-tdl)!: Add support for an optional init hook run once when a TDL package is loaded. Jul 18, 2026
@LinZhihao-723
LinZhihao-723 merged commit 95b779c into y-scope:main Jul 18, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants