Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(proxy-wasm) foreign function support #626

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

casimiro
Copy link
Contributor

@casimiro casimiro commented Nov 18, 2024

Foreign Function Support

The Proxy-Wasm spec defines the function proxy_call_foreign_function and the callback proxy_on_foreign_function that filter developers can use to invoke host specific functions, a.k.a. foreign functions, and receive callbacks.

A foreign function invoked with proxy_call_foreign_function may return its value immediately -- as part of the returned value of the proxy_call_foreign_function call; or it can return it later, writing it to the FOREIGN_FUNCTION_ARGUMENTS buffer, and invoking proxy_on_foreign_function with an id identifying the function initially called.

This PR adds support for the mechanism described above; and although the spec doesn't restrict when foreign functions can be called, in ngx_wasm_module they cannot be invoked from proxy_on_configure or proxy_on_vm_start.

DNS resolution

This PR also exposes the Lua DNS resolver through the resolve_lua foreign function.

This function expects the name to be resolved as its single argument. If the name can be resolved without performing any IO, the resolved address is put in the returned value of proxy_call_foreign_function.

If the resolver needs to forward the resolution request to a DNS server, the resolved address and the name itself are written to the FOREIGN_FUNCTION_ARGUMENTS buffer and the proxy_on_foreign_function callback is invoked with function_id 0, as soon as the address is returned from the server.

TODO

  • on_tick support
  • general review
  • update docs

@casimiro casimiro added the pr/work-in-progress PR: Work in progress label Nov 18, 2024
@casimiro casimiro force-pushed the feat/wasm-foreign-function branch 5 times, most recently from d4b4267 to 99b8e75 Compare November 19, 2024 21:58
Copy link

codecov bot commented Nov 19, 2024

Codecov Report

Attention: Patch coverage is 82.97872% with 48 lines in your changes missing coverage. Please review.

Project coverage is 90.73090%. Comparing base (d834bb0) to head (d217d1a).
Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
...rc/common/proxy_wasm/ngx_proxy_wasm_foreign_call.c 76.00000% 36 Missing ⚠️
src/common/proxy_wasm/ngx_proxy_wasm_host.c 87.50000% 3 Missing ⚠️
src/http/ngx_http_wasm_util.c 80.00000% 3 Missing ⚠️
src/http/proxy_wasm/ngx_http_proxy_wasm.c 84.21053% 3 Missing ⚠️
src/http/proxy_wasm/ngx_http_proxy_wasm_dispatch.c 93.75000% 2 Missing ⚠️
src/common/proxy_wasm/ngx_proxy_wasm.c 96.15385% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@                 Coverage Diff                 @@
##                main        #626         +/-   ##
===================================================
- Coverage   90.84288%   90.73090%   -0.11198%     
===================================================
  Files             52          53          +1     
  Lines          11259       11479        +220     
===================================================
+ Hits           10228       10415        +187     
- Misses          1031        1064         +33     
Files with missing lines Coverage Δ
src/common/proxy_wasm/ngx_proxy_wasm.h 92.30769% <ø> (ø)
src/common/proxy_wasm/ngx_proxy_wasm_maps.c 94.01042% <100.00000%> (ø)
src/common/proxy_wasm/ngx_proxy_wasm_util.c 94.25287% <100.00000%> (ø)
src/common/proxy_wasm/ngx_proxy_wasm.c 92.66451% <96.15385%> (-0.01309%) ⬇️
src/http/proxy_wasm/ngx_http_proxy_wasm_dispatch.c 91.74528% <93.75000%> (+0.31671%) ⬆️
src/common/proxy_wasm/ngx_proxy_wasm_host.c 93.61233% <87.50000%> (-0.18699%) ⬇️
src/http/ngx_http_wasm_util.c 86.95652% <80.00000%> (-0.27752%) ⬇️
src/http/proxy_wasm/ngx_http_proxy_wasm.c 92.99065% <84.21053%> (-0.88690%) ⬇️
...rc/common/proxy_wasm/ngx_proxy_wasm_foreign_call.c 76.00000% <76.00000%> (ø)

... and 2 files with indirect coverage changes

Flag Coverage Δ
unit 90.67342% <90.36145%> (+0.06802%) ⬆️
valgrind 81.06350% <29.41176%> (-1.38648%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

@casimiro casimiro force-pushed the feat/wasm-foreign-function branch from 99b8e75 to 5bb49f5 Compare November 20, 2024 12:01
@casimiro casimiro changed the title feat(proxy-wasm) foreign function feat(proxy-wasm) foreign function support Nov 20, 2024
@casimiro casimiro force-pushed the feat/wasm-foreign-function branch 5 times, most recently from 08ec198 to 2ecb389 Compare November 21, 2024 13:28
@casimiro casimiro force-pushed the feat/wasm-foreign-function branch 6 times, most recently from b4d763b to 370b775 Compare November 26, 2024 22:31
@casimiro casimiro force-pushed the feat/wasm-foreign-function branch from 370b775 to 20d5be4 Compare November 27, 2024 00:24
Making struct member names explict to distinguish them from the upcoming
Proxy-Wasm foreign call support.
@casimiro casimiro force-pushed the feat/wasm-foreign-function branch from 20d5be4 to 9910a5b Compare November 27, 2024 00:34
@casimiro casimiro force-pushed the feat/wasm-foreign-function branch 5 times, most recently from b661016 to 0d11869 Compare November 27, 2024 17:15
@casimiro
Copy link
Contributor Author

Codecov is playing games with me. It's reporting lines that are definitely covered by tests as uncovered.

@casimiro casimiro force-pushed the feat/wasm-foreign-function branch 2 times, most recently from 90edd6e to b8d786f Compare December 2, 2024 22:01
util/morestyle.pl Show resolved Hide resolved
config Outdated Show resolved Hide resolved
config Show resolved Hide resolved
src/common/proxy_wasm/ngx_proxy_wasm.h Outdated Show resolved Hide resolved
src/http/proxy_wasm/ngx_http_proxy_wasm_dispatch.c Outdated Show resolved Hide resolved
[error]
can only call resolve_lua during "on_request_headers", "on_request_body", "on_dispatch_response", "on_tick", "on_foreign_function"
--- no_error_log
[crit]
Copy link
Member

Choose a reason for hiding this comment

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

Technically, we would have to also add a new test case to all context checks for the new on_foreign_call step... I was going to say we can factorize both those steps together (since they both are "background calls"), but we may want some functions to be disabled in one but not the other...

This makes me think of some cases that we ought to test, for example making a dispatch call during on_foreign_call and vice-versa... This test is also relevant as we factorize both call queues. Maybe we ought to add the new step to the context tests...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, as I was implementing support for calling lua_resolver from on_http_call_response I noticed that the code also allowed for calling dispatch_http_call from on_foreign_call and that on_foreign_call would be an additional check in the context tests for the hostcalls.

There's a test asserting that filter developers can call the lua_resolver from the on_http_call_response callback; but tests not strictly related to the lua_resolver function (e.g. calling http_call from on_foreign_call and the new on_foreign_call check in the context checks) were left to be addressed in a separate PR as this one is already rather large.

I can include them in this PR. though; if you prefer that way.

I agree that there's value in keeping them separate.

Copy link
Member

Choose a reason for hiding this comment

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

tests not strictly related to the lua_resolver function (e.g. calling http_call from on_foreign_call and the new on_foreign_call check in the context checks) were left to be addressed in a separate PR as this one is already rather large.

Let's add them in this PR, they belong to this feature and that way it will be done. The PR is not very large to me, it's alright.

@@ -8,7 +8,8 @@ edition = "2018"
crate-type = ["cdylib"]

[dependencies]
proxy-wasm = "0.2"
#proxy-wasm = "0.2"
proxy-wasm = { git = "https://github.com/casimiro/proxy-wasm-rust-sdk.git", branch = "foreign-function-callback" }
Copy link
Member

Choose a reason for hiding this comment

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

Hmmmm, this may be a blocker until it is merged upstream... Actually, getting the feature merged upstream may be a requirement for merging this PR, don't you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I was hoping the changes in the upstream would be merged by the end of this PR.

On one hand, this workaround seems very subpar and makes me want to consider it a blocker.

On the other, that separate branch contains a single commit that's already been approved by the maintainers and should be part of the next release; and using this separate branch would allow us to ship foreign function support in time for the 3.9 release of the gateway.

src/common/proxy_wasm/ngx_proxy_wasm.h Show resolved Hide resolved
@casimiro casimiro force-pushed the feat/wasm-foreign-function branch 5 times, most recently from 87e0f67 to 7eb64b5 Compare December 10, 2024 18:04
…aration

Handles the case when the expression defining a variable being declared
is a function call receiving arguments that don't fit in the same line,
e.g.:

ngx_proxy_wasm_exec_t          *pwexec = ngx_proxy_wasm_instance2pwexec(
                                             instance);
The trap message describing the lua_resolver being called in unsupported
context exceeds the current limit.
@casimiro casimiro force-pushed the feat/wasm-foreign-function branch from 7eb64b5 to d217d1a Compare December 10, 2024 19:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr/work-in-progress PR: Work in progress
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants