Skip to content

[ISSUE #7562] Forward wasm discovery upstream deletion events. - #7568

Merged
Aias00 merged 1 commit into
apache:masterfrom
yangjj-iso:fix/7562-wasm-discovery-delete
Oct 12, 2026
Merged

Aias00 merged 1 commit into
apache:masterfrom
yangjj-iso:fix/7562-wasm-discovery-delete

Conversation

@yangjj-iso

Copy link
Copy Markdown
Contributor

Fixes #7562.

Discovery deletions now invoke the optional guest export removeDiscoveryUpstreamData(i64) -> (). The callback reuses the existing argument ID and ARGUMENTS bridge, carrying a DiscoverySyncData with the key's plugin name, selector ID, and optional selector name. Temporary arguments are cleared on success and failure, and existing Java subclasses need no new abstract method.

Guests without the deletion export retain the legacy no-op behavior. WasmLoader.getWasmExtern checks export presence before calling Chicory, returning an empty optional for absent exports while still rejecting exports of the wrong kind. The callback contract is documented in Javadoc and the WASM base module README.

Go and Rust fixtures were rebuilt. Tests cover direct deletion, update followed by subscriber deletion, nullable selector names, callback failure cleanup, and an original Go guest without the optional export. The deletion regression tests fail against the original handler (6 failures) and pass with the fix.

Validation: 34 tests passed, including all WASM API/base tests and the discovery subscriber test. Checkstyle and Apache RAT passed in the dependency reactor:

./mvnw -pl shenyu-plugin/shenyu-plugin-wasm-base -am verify '-Dtest=AbstractWasm*Test,AbstractShenyuWasmPluginTest,CommonDiscoveryUpstreamDataSubscriberTest' -Dsurefire.failIfNoSpecifiedTests=false -Dmaven.javadoc.skip=true -Djacoco.skip=true

Make sure that:

  • You have read the contribution guidelines.
  • You submit test cases (unit or integration tests) that back your changes.
  • Your local test passed ./mvnw clean install -Dmaven.javadoc.skip=true. (Full repository build not run; the affected module and its dependency reactor passed the verification command above.)

@wy471x wy471x 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.

The deletion forwarding itself is correct and the interface default keeps existing implementers source-compatible: DiscoveryUpstreamDataHandler already declares removeDiscoveryUpstreamData as a default no-op, so overriding it adds behaviour without a new abstract method.

Verified locally on this head (JDK 21, wasm-api + wasm-base reactor):

  • wasm-api AbstractWasmPluginTest 4/4 (including the two new export-lookup cases), wasm-base AbstractWasmDiscoveryHandlerTest 9/9, AbstractWasmPluginDataHandlerTest 12/12, AbstractWasmMetaDataHandlerTest 2/2, CommonDiscoveryUpstreamDataSubscriberTest 1/1 — all green; checkstyle 0 violations; apache-rat:check 0 unapproved on both modules.
  • The legacy-guest path is genuinely covered: TestLegacyWasmPluginDiscoveryHandler keeps the old Go binary that exports only the update callback, and both the direct and subscriber calls remain no-ops.

Coordination issue (not a defect in this diff, but it blocks clean merging). This PR replaces WasmLoader.getWasmExtern with the same "look up the export section before calling Chicory" change that #7567 (draft) and #7569 make, all from the same base revision. Whichever of the three lands second will conflict on those lines. Worse, the policies disagree:

  • #7568 (and #7567) keep instance.export(name) for a non-function export, so getWasmExtern("memory") throws InvalidException — asserted by this PR's nonFunctionExportStillFailsTest.
  • #7569 filters on exportType() == FUNCTION and returns empty for the same input — asserted by WasmLoaderTest.lookupReturnsOnlyExportedFunctions.

I confirmed the contradiction against the code: I applied #7569's implementation and ran #7568's nonFunctionExportStillFailsTest assertion; it fails with Expected com.dylibso.chicory.wasm.InvalidException to be thrown, but nothing was thrown. Both PRs' own suites are green precisely because they encode different contracts, so they cannot both merge as written.

Please agree one policy with the other WASM PRs, land the lookup change once (ideally as the shared findWasmExtern helper in #7567 and rebase #7568/#7569 on it), and remove the duplicated hunk here. If the intended contract is "missing export stays optional, wrong-kind export still fails", #7568/#7567's policy is the one to standardise on; if non-function exports should also be treated as absent, #7569's is.

Notes (non-blocking):

  • The deletion callback synthesises a DiscoverySyncData carrying only pluginName / selectorId / selectorName from the key; everything else is null. The README documents this. If a guest ever needs namespace or handler id on delete, the DiscoveryUpstreamKey/payload would need to grow — worth stating explicitly as a current limitation.
  • WasmLoader.getWasmExtern("_initialize") is still driven by the old try/catch InvalidException in the constructor here, so the "optional export" fix only covers callers going through getWasmExtern. Consolidating on findWasmExtern (as #7567 does) would fix both consistently.

@Aias00 Aias00 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.

Approve. This forwards discovery-upstream deletion to the optional WASM guest export removeDiscoveryUpstreamData, and it is implemented with clean backward compatibility.

What I checked:

  • AbstractWasmDiscoveryHandler.removeDiscoveryUpstreamData(DiscoveryUpstreamKey key) is an @Override of the existing DiscoveryUpstreamDataHandler interface method (the subscriber already calls it), so this PR only provides the previously-missing WASM bridge implementation.
  • The handler builds a DiscoverySyncData carrying only the key's pluginName/selectorId/selectorName (other fields null) and forwards it via the existing callWASI helper, which still removes the argument in finally (including on guest failure — verified by deletionFailureRemovesArgumentsTest).
  • Guests without the removeDiscoveryUpstreamData export keep the legacy no-op behavior: super.getWasmExtern(REMOVE_METHOD_NAME).ifPresent(...) simply does nothing. missingOptionalDeletionExportTest / TestLegacyWasmPluginDiscoveryHandler cover this.
  • WasmLoader.getWasmExtern now iterates the export section to match by name (and the parallel #7569 change adds the ExternalType.FUNCTION guard), so non-function exports are handled without throwing.
  • Both Go and Rust test guests were updated to export the new callback, with buffer size bumped to 1024 and JSON round-trip assertions; tests are parametrized over Go/Rust.

This is a coherent feature addition with solid regression coverage. No blocking issues.

@Aias00
Aias00 merged commit d671076 into apache:master Oct 12, 2026
27 checks passed
@Aias00 Aias00 added this to the 2.7.2 milestone Nov 13, 2026
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.

[BUG] AbstractWasmDiscoveryHandler does not forward upstream deletion events

3 participants