From ab7f0f09eadca8299a323ae196f2ff4dedd3d7d3 Mon Sep 17 00:00:00 2001 From: Trevor Elliott Date: Tue, 13 Aug 2024 15:16:07 -0700 Subject: [PATCH] Update compute.wit and the adapter for some api fixes (#414) While implementing compute.wit elsewhere, I made a few changes that better reflect the translation to the underlying hostcalls. This PR backports those changes to compute.wit, and folds them in to the adapter and component implementation. --- crates/adapter/src/fastly/cache.rs | 13 ++++++-- crates/adapter/src/fastly/core.rs | 34 ++++++++++++--------- lib/data/viceroy-component-adapter.wasm | Bin 177177 -> 178156 bytes lib/src/component/backend.rs | 8 ++--- lib/src/component/cache.rs | 6 +++- lib/src/component/config_store.rs | 4 +-- lib/src/component/device_detection.rs | 4 +-- lib/src/component/dictionary.rs | 4 +-- lib/src/component/error.rs | 7 +++-- lib/src/component/geo.rs | 4 +-- lib/src/component/http_req.rs | 10 +++--- lib/src/component/secret_store.rs | 8 ++--- lib/wit/deps/fastly/compute.wit | 39 ++++++++++++++---------- 13 files changed, 83 insertions(+), 58 deletions(-) diff --git a/crates/adapter/src/fastly/cache.rs b/crates/adapter/src/fastly/cache.rs index d493fa0a..1d0a9652 100644 --- a/crates/adapter/src/fastly/cache.rs +++ b/crates/adapter/src/fastly/cache.rs @@ -1,5 +1,5 @@ use super::{convert_result, BodyHandle, FastlyStatus, RequestHandle}; -use crate::{alloc_result, TrappingUnwrap}; +use crate::{alloc_result_opt, TrappingUnwrap}; pub type CacheHandle = u32; @@ -35,6 +35,7 @@ pub struct CacheWriteOptions { pub length: CacheObjectLength, pub user_metadata_ptr: *const u8, pub user_metadata_len: usize, + pub edge_max_age_ns: u64, } bitflags::bitflags! { @@ -198,6 +199,7 @@ mod cache { surrogate_keys: make_vec!(surrogate_keys_ptr, surrogate_keys_len), length: (*options).length, user_metadata: make_vec!(user_metadata_ptr, user_metadata_len), + edge_max_age_ns: (*options).edge_max_age_ns, } } @@ -345,11 +347,16 @@ mod cache { user_metadata_out_len: usize, nwritten_out: *mut usize, ) -> FastlyStatus { - alloc_result!( + alloc_result_opt!( user_metadata_out_ptr, user_metadata_out_len, nwritten_out, - { cache::get_user_metadata(handle) } + { + cache::get_user_metadata( + handle, + u64::try_from(user_metadata_out_len).trapping_unwrap(), + ) + } ) } diff --git a/crates/adapter/src/fastly/core.rs b/crates/adapter/src/fastly/core.rs index 493d3cc0..587074f9 100644 --- a/crates/adapter/src/fastly/core.rs +++ b/crates/adapter/src/fastly/core.rs @@ -1346,16 +1346,17 @@ pub mod fastly_http_req { FastlyStatus::OK } - Err((detail, e)) => { + Err(err) => { unsafe { - *error_detail = detail + *error_detail = err + .detail .unwrap_or_else(|| http_req::SendErrorDetailTag::Uninitialized.into()) .into(); *resp_handle_out = INVALID_HANDLE; *resp_body_handle_out = INVALID_HANDLE; } - e.into() + err.error.into() } } } @@ -1556,16 +1557,17 @@ pub mod fastly_http_req { FastlyStatus::OK }, - Err((detail, e)) => { + Err(err) => { unsafe { - *error_detail = detail + *error_detail = err + .detail .unwrap_or_else(|| http_req::SendErrorDetailTag::Uninitialized.into()) .into(); *is_done_out = 0; *resp_handle_out = INVALID_HANDLE; *resp_body_handle_out = INVALID_HANDLE; } - e.into() + err.error.into() } } } @@ -1614,15 +1616,16 @@ pub mod fastly_http_req { } FastlyStatus::OK } - Err((detail, e)) => { + Err(err) => { unsafe { - *error_detail = detail + *error_detail = err + .detail .unwrap_or_else(|| http_req::SendErrorDetailTag::Uninitialized.into()) .into(); *resp_handle_out = INVALID_HANDLE; *resp_body_handle_out = INVALID_HANDLE; } - e.into() + err.error.into() } } } @@ -1644,15 +1647,16 @@ pub mod fastly_http_req { FastlyStatus::OK } - Err((detail, e)) => { + Err(err) => { unsafe { - *error_detail = detail + *error_detail = err + .detail .unwrap_or_else(|| http_req::SendErrorDetailTag::Uninitialized.into()) .into(); *resp_handle_out = INVALID_HANDLE; *resp_body_handle_out = INVALID_HANDLE; } - e.into() + err.error.into() } } } @@ -2654,12 +2658,13 @@ pub mod fastly_backend { ) -> FastlyStatus { let backend = unsafe { slice::from_raw_parts(backend_ptr, backend_len) }; match backend::get_ssl_min_version(backend) { - Ok(res) => { + Ok(Some(res)) => { unsafe { *value = u32::from(res); } FastlyStatus::OK } + Ok(None) => FastlyStatus::NONE, Err(e) => e.into(), } } @@ -2672,12 +2677,13 @@ pub mod fastly_backend { ) -> FastlyStatus { let backend = unsafe { slice::from_raw_parts(backend_ptr, backend_len) }; match backend::get_ssl_max_version(backend) { - Ok(res) => { + Ok(Some(res)) => { unsafe { *value = u32::from(res); } FastlyStatus::OK } + Ok(None) => FastlyStatus::NONE, Err(e) => e.into(), } } diff --git a/lib/data/viceroy-component-adapter.wasm b/lib/data/viceroy-component-adapter.wasm index 000703bdc344011cdd1d86cf0e7e9223abe85359..3e4b97d4eba2cabb5500208b14378f77342a5776 100755 GIT binary patch delta 31126 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 delta 31640 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 Nw0cos-|wIk{txw$1~UKv diff --git a/lib/src/component/backend.rs b/lib/src/component/backend.rs index 44513183..0fdadd5a 100644 --- a/lib/src/component/backend.rs +++ b/lib/src/component/backend.rs @@ -48,7 +48,7 @@ impl backend::Host for Session { &mut self, backend: String, max_len: u64, - ) -> Result, types::Error> { + ) -> Result>, types::Error> { let backend = self.backend(&backend).ok_or(Error::InvalidArgument)?; if let Some(host) = backend.override_host.as_ref() { let host = host.to_str()?; @@ -61,7 +61,7 @@ impl backend::Host for Session { .into()); } - Ok(Some(String::from(host))) + Ok(Some(host.as_bytes().to_owned())) } else { Ok(None) } @@ -116,7 +116,7 @@ impl backend::Host for Session { async fn get_ssl_min_version( &mut self, backend: String, - ) -> Result { + ) -> Result, types::Error> { // just doing this to get a different error if the backend doesn't exist let _ = self.backend(&backend).ok_or(Error::InvalidArgument)?; // health checks are not enabled in Viceroy :( @@ -129,7 +129,7 @@ impl backend::Host for Session { async fn get_ssl_max_version( &mut self, backend: String, - ) -> Result { + ) -> Result, types::Error> { // just doing this to get a different error if the backend doesn't exist let _ = self.backend(&backend).ok_or(Error::InvalidArgument)?; // health checks are not enabled in Viceroy :( diff --git a/lib/src/component/cache.rs b/lib/src/component/cache.rs index dc35767c..920f2e69 100644 --- a/lib/src/component/cache.rs +++ b/lib/src/component/cache.rs @@ -142,7 +142,11 @@ impl cache::Host for Session { .into()) } - async fn get_user_metadata(&mut self, _handle: cache::Handle) -> Result { + async fn get_user_metadata( + &mut self, + _handle: cache::Handle, + _max_len: u64, + ) -> Result>, types::Error> { Err(Error::Unsupported { msg: "Cache API primitives not yet supported", } diff --git a/lib/src/component/config_store.rs b/lib/src/component/config_store.rs index d807c901..b97293e7 100644 --- a/lib/src/component/config_store.rs +++ b/lib/src/component/config_store.rs @@ -15,7 +15,7 @@ impl config_store::Host for Session { store: config_store::Handle, name: String, max_len: u64, - ) -> Result, types::Error> { + ) -> Result>, types::Error> { let dict = &self.dictionary(store.into())?.contents; let item = if let Some(item) = dict.get(&name) { @@ -28,6 +28,6 @@ impl config_store::Host for Session { return Err(types::Error::BufferLen(u64::try_from(item.len()).unwrap())); } - Ok(Some(item.clone())) + Ok(Some(item.as_bytes().to_owned())) } } diff --git a/lib/src/component/device_detection.rs b/lib/src/component/device_detection.rs index f7fa7efc..efd83939 100644 --- a/lib/src/component/device_detection.rs +++ b/lib/src/component/device_detection.rs @@ -9,7 +9,7 @@ impl device_detection::Host for Session { &mut self, user_agent: String, max_len: u64, - ) -> Result, types::Error> { + ) -> Result>, types::Error> { if let Some(result) = self.device_detection_lookup(&user_agent) { if result.len() > max_len as usize { return Err(types::Error::BufferLen( @@ -17,7 +17,7 @@ impl device_detection::Host for Session { )); } - Ok(Some(result)) + Ok(Some(result.into_bytes())) } else { Ok(None) } diff --git a/lib/src/component/dictionary.rs b/lib/src/component/dictionary.rs index 9dfbc5ca..e9126619 100644 --- a/lib/src/component/dictionary.rs +++ b/lib/src/component/dictionary.rs @@ -15,7 +15,7 @@ impl dictionary::Host for Session { h: dictionary::Handle, key: String, max_len: u64, - ) -> Result, types::Error> { + ) -> Result>, types::Error> { let dict = &self.dictionary(h.into())?.contents; let item = if let Some(item) = dict.get(&key) { @@ -28,6 +28,6 @@ impl dictionary::Host for Session { return Err(types::Error::BufferLen(u64::try_from(item.len()).unwrap())); } - Ok(Some(item.clone())) + Ok(Some(item.as_bytes().to_owned())) } } diff --git a/lib/src/component/error.rs b/lib/src/component/error.rs index c7fab6d7..98e69cc6 100644 --- a/lib/src/component/error.rs +++ b/lib/src/component/error.rs @@ -15,8 +15,11 @@ use { }; impl types::Error { - pub fn with_empty_detail(self) -> (Option, Self) { - (None, self) + pub fn with_empty_detail(self) -> http_req::ErrorWithDetail { + http_req::ErrorWithDetail { + detail: None, + error: self, + } } } diff --git a/lib/src/component/geo.rs b/lib/src/component/geo.rs index 4d18d1df..5b5af5ba 100644 --- a/lib/src/component/geo.rs +++ b/lib/src/component/geo.rs @@ -6,7 +6,7 @@ use { #[async_trait::async_trait] impl geo::Host for Session { - async fn lookup(&mut self, octets: Vec, max_len: u64) -> Result { + async fn lookup(&mut self, octets: Vec, max_len: u64) -> Result, types::Error> { let ip_addr: IpAddr = match octets.len() { 4 => IpAddr::V4(Ipv4Addr::from( TryInto::<[u8; 4]>::try_into(octets).unwrap(), @@ -29,6 +29,6 @@ impl geo::Host for Session { .into()); } - Ok(json) + Ok(json.into_bytes()) } } diff --git a/lib/src/component/http_req.rs b/lib/src/component/http_req.rs index 32fb6841..d8f7118f 100644 --- a/lib/src/component/http_req.rs +++ b/lib/src/component/http_req.rs @@ -408,7 +408,7 @@ impl http_req::Host for Session { h: http_types::RequestHandle, b: http_types::BodyHandle, backend_name: String, - ) -> Result, types::Error)> { + ) -> Result { // This initial implementation ignores the error detail field self.send(h, b, backend_name) .await @@ -478,8 +478,7 @@ impl http_req::Host for Session { async fn pending_req_poll_v2( &mut self, h: http_types::PendingRequestHandle, - ) -> Result, (Option, types::Error)> - { + ) -> Result, http_req::ErrorWithDetail> { self.pending_req_poll(h) .await .map_err(types::Error::with_empty_detail) @@ -497,7 +496,7 @@ impl http_req::Host for Session { async fn pending_req_wait_v2( &mut self, h: http_types::PendingRequestHandle, - ) -> Result, types::Error)> { + ) -> Result { self.pending_req_wait(h) .await .map_err(types::Error::with_empty_detail) @@ -550,8 +549,7 @@ impl http_req::Host for Session { async fn pending_req_select_v2( &mut self, h: Vec, - ) -> Result<(u32, http_types::Response), (Option, types::Error)> - { + ) -> Result<(u32, http_types::Response), http_req::ErrorWithDetail> { self.pending_req_select(h) .await .map_err(types::Error::with_empty_detail) diff --git a/lib/src/component/secret_store.rs b/lib/src/component/secret_store.rs index edfb8dc4..b33f1dc6 100644 --- a/lib/src/component/secret_store.rs +++ b/lib/src/component/secret_store.rs @@ -33,7 +33,7 @@ impl secret_store::Host for Session { &mut self, secret: secret_store::SecretHandle, max_len: u64, - ) -> Result, types::Error> { + ) -> Result>, types::Error> { let lookup = self .secret_lookup(secret.into()) .ok_or(Error::SecretStoreError( @@ -67,13 +67,13 @@ impl secret_store::Host for Session { .into()); } - Ok(Some(String::from(std::str::from_utf8(plaintext)?))) + Ok(Some(plaintext.to_owned())) } async fn from_bytes( &mut self, - plaintext: String, + plaintext: Vec, ) -> Result { - Ok(self.add_secret(Vec::from(plaintext.as_bytes())).into()) + Ok(self.add_secret(plaintext).into()) } } diff --git a/lib/wit/deps/fastly/compute.wit b/lib/wit/deps/fastly/compute.wit index a7dcb7ce..21c9fdb2 100644 --- a/lib/wit/deps/fastly/compute.wit +++ b/lib/wit/deps/fastly/compute.wit @@ -284,6 +284,11 @@ interface http-req { tls-alert-id: u8, } + record error-with-detail { + detail: option, + error: error, + } + cache-override-set: func( h: request-handle, tag: cache-override-tag, @@ -391,7 +396,7 @@ interface http-req { h: request-handle, b: body-handle, backend: string, - ) -> result, error>>; + ) -> result; send-async: func(h: request-handle, b: body-handle, backend: string) -> result; @@ -405,13 +410,13 @@ result; pending-req-poll-v2: func( h: pending-request-handle, - ) -> result, tuple, error>>; + ) -> result, error-with-detail>; pending-req-wait: func(h: pending-request-handle) -> result; pending-req-wait-v2: func( h: pending-request-handle - ) -> result, error>>; + ) -> result; pending-req-select: func( h: list @@ -419,7 +424,7 @@ result; pending-req-select-v2: func( h: list - ) -> result, tuple, error>>; + ) -> result, error-with-detail>; fastly-key-is-valid: func() -> result; @@ -566,7 +571,7 @@ interface dictionary { h: handle, key: string, max-len: u64, - ) -> result, error>; + ) -> result>, error>; } /* @@ -575,7 +580,7 @@ interface dictionary { interface geo { use types.{error}; - lookup: func(addr-octets: list, max-len: u64) -> result; + lookup: func(addr-octets: list, max-len: u64) -> result, error>; } /* @@ -584,7 +589,7 @@ interface geo { interface device-detection { use types.{error}; - lookup: func(user-agent: string, max-len: u64) -> result, error>; + lookup: func(user-agent: string, max-len: u64) -> result>, error>; } /* @@ -707,9 +712,9 @@ interface secret-store { plaintext: func( secret: secret-handle, max-len: u64 - ) -> result, error>; + ) -> result>, error>; - from-bytes: func(bytes: string) -> result; + from-bytes: func(bytes: list) -> result; } /* @@ -742,7 +747,7 @@ interface backend { get-override-host: func( backend: string, max-len: u64, - ) -> result, error>; + ) -> result>, error>; /// Get the remote TCP port of the backend connection for the request. get-port: func(backend: string) -> result; @@ -760,10 +765,10 @@ interface backend { is-ssl: func(backend: string) -> result; /// Get the minimum SSL version this backend will use. - get-ssl-min-version: func(backend: string) -> result; + get-ssl-min-version: func(backend: string) -> result, error>; /// Get the maximum SSL version this backend will use. - get-ssl-max-version: func(backend: string) -> result; + get-ssl-max-version: func(backend: string) -> result, error>; } /* @@ -868,6 +873,7 @@ interface cache { length, user-metadata, sensitive-data, + edge-max-age-ns, } /// Configuration for several hostcalls that write to the cache: @@ -894,6 +900,7 @@ interface cache { surrogate-keys: string, length: object-length, user-metadata: list, + edge-max-age-ns: duration-ns, } flags get-body-options-mask { @@ -1020,9 +1027,9 @@ interface cache { get-state: func(handle: handle) -> result; - /// Gets the user metadata of the found object, returning the `optional-none` error if there - /// was no found object. - get-user-metadata: func(handle: handle) -> result; + /// Gets the user metadata of the found object, returning None if no object + /// was found. + get-user-metadata: func(handle: handle, max-len: u64) -> result>, error>; /// Gets a range of the found object body, returning the `optional-none` error if there /// was no found object. @@ -1073,7 +1080,7 @@ interface config-store { store: handle, key: string, max-len: u64, - ) -> result, error>; + ) -> result>, error>; } interface reactor {