Skip to content

feat: change engine proxy to use flatbuffer implementation over wasm#333

Merged
chriswk merged 17 commits intomainfrom
fix/ffiFlat
Nov 13, 2025
Merged

feat: change engine proxy to use flatbuffer implementation over wasm#333
chriswk merged 17 commits intomainfrom
fix/ffiFlat

Conversation

@chriswk
Copy link
Copy Markdown
Member

@chriswk chriswk commented Nov 10, 2025

This patches v11, we should probably also look at updating v10. But for now, this PR allows us to create an RC/beta that can run in our infrastructure to allow us to verify memory usage and performance.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR updates the SDK to replace WasmResponse with FlatResponse as part of migrating to a newer engine version (yggdrasil-engine 0.4.3). It also includes dependency updates, infrastructure improvements, and example project enhancements.

  • Renamed WasmResponse to FlatResponse throughout the codebase
  • Updated dependencies including Spring Boot (3.5.7), Gradle (9.1.0), and various libraries
  • Added native image example with GraalVM support
  • Improved test utilities with new ResourceReader class

Reviewed Changes

Copilot reviewed 25 out of 27 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/main/java/io/getunleash/DefaultUnleash.java Updated to use FlatResponse with Optional handling for null safety
src/main/java/io/getunleash/EngineProxyImpl.java Changed return types from WasmResponse to FlatResponse
src/main/java/io/getunleash/repository/*.java Updated method signatures to use FlatResponse
src/test/java/io/getunleash/util/ResourceReader.java New utility class for reading test resources
pom.xml Updated yggdrasil-engine to 0.4.3, upgraded dependencies, reorganized properties
examples/spring-boot-example/* Updated Spring Boot to 3.5.7, added dev tools, fixed annotation usage
examples/native-image-example/* New example demonstrating GraalVM native image support

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/main/java/io/getunleash/DefaultUnleash.java Outdated
@chriswk chriswk enabled auto-merge (squash) November 10, 2025 12:56
FlatResponse<Boolean> isEnabled(String toggleName, UnleashContext context);

WasmResponse<VariantDef> getVariant(String toggleName, UnleashContext context);
FlatResponse<VariantDef> getVariant(String toggleName, UnleashContext context);
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.

This seems also nullable.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

yeah, true, thanks

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

.NET is expecting these to not be null I believe

WasmResponse<VariantDef> response =
FlatResponse<VariantDef> response =
this.featureRepository.getVariant(toggleName, enhancedContext);
Optional<VariantDef> variantDef = Optional.ofNullable(response.value);
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.

This can give nullpointer exception, if response is null.

Optional<VariantDef> variantDef = Optional.ofNullable(response.value);
Optional<FlatResponse<VariantDef>> response =
Optional.ofNullable(this.featureRepository.getVariant(toggleName, enhancedContext));
Optional<VariantDef> variantDef = response.map(r -> r.value);
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.

I think now if we call variantDef.get() you might get null as result, but you actually want isPresent to return false?

I think we want Optional<VariantDef> variantDef = response.flatMap(r -> Optional.ofNullable(r.value));

This is what we do in https://github.com/Unleash/unleash-java-sdk/pull/333/files#diff-5209f3f32d148f4e260e39b0166a5cd032fdc210bd83b0859993c254d4325263R119

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I agree monadically / if java actually did optionals the expected way, but as I just confirmed with jshell, when you map an option, if your option returns null, you get Optional.empty, not an NPE

jshell> Optional<String> my_present = Optional.of("hello");
my_present ==> Optional[hello]

jshell> Optional<String> absent = my_present.map(s -> null)
absent ==> Optional.empty

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.

Oh wow, nice!

@coveralls
Copy link
Copy Markdown
Collaborator

coveralls commented Nov 10, 2025

Pull Request Test Coverage Report for Build 19326878737

Details

  • 11 of 11 (100.0%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.2%) to 79.262%

Totals Coverage Status
Change from base Build 18901356217: 0.2%
Covered Lines: 2483
Relevant Lines: 3060

💛 - Coveralls

@chriswk chriswk moved this from New to In Progress in Issues and PRs Nov 11, 2025
Comment on lines +16 to +18
getOrElse("UNLEASH_API_TOKEN",
"*:development.25a06b75248528f8ca93ce179dcdd141aedfb632231e0d21fd8ff349"))
.unleashAPI(getOrElse("UNLEASH_API_URL", "https://app.unleash-hosted.com/demo/api"))
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Good enough for now I guess, but yeah maybe should've been env arg?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It is an env arg. we just default to one that used to be able to access demo, but since we wipe demo regularly, I'm not worried.

Comment on lines +16 to +17
getOrElse("UNLEASH_API_TOKEN",
"*:development.25a06b75248528f8ca93ce179dcdd141aedfb632231e0d21fd8ff349"))
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Same

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

same

Comment on lines +2 to +3
url: http://localhost:4242/api
apiKey: "*:development.da33883b2b2be02c5648ac624a1f50922cbc5893c2e6de5b9f57298d"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

this isn't going to work is it?

Copy link
Copy Markdown

@daveleek daveleek left a comment

Choose a reason for hiding this comment

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

Cool :)

@chriswk chriswk merged commit e92733d into main Nov 13, 2025
9 checks passed
@chriswk chriswk deleted the fix/ffiFlat branch November 13, 2025 14:15
@github-project-automation github-project-automation Bot moved this from In Progress to Done in Issues and PRs Nov 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants