From a8e5cec8325ea7bb134fef2045a6dc4d910c28aa Mon Sep 17 00:00:00 2001 From: computermouth Date: Wed, 30 Oct 2024 13:26:21 -0600 Subject: [PATCH 1/2] Add new lookup_wait_v2 to fix generation parsing bug --- crates/adapter/src/fastly/core.rs | 62 +++++++++++++++++++- lib/compute-at-edge-abi/compute-at-edge.witx | 13 ++++ lib/compute-at-edge-abi/typenames.witx | 7 ++- lib/src/component/kv_store.rs | 4 +- lib/src/object_store.rs | 6 +- lib/src/session.rs | 2 +- lib/src/wiggle_abi.rs | 2 +- lib/src/wiggle_abi/kv_store_impl.rs | 51 ++++++++++++++++ lib/wit/deps/fastly/compute.wit | 4 +- 9 files changed, 138 insertions(+), 13 deletions(-) diff --git a/crates/adapter/src/fastly/core.rs b/crates/adapter/src/fastly/core.rs index ffbd1114..8c45d638 100644 --- a/crates/adapter/src/fastly/core.rs +++ b/crates/adapter/src/fastly/core.rs @@ -2511,7 +2511,7 @@ pub mod fastly_kv_store { #[repr(C)] pub struct InsertConfig { pub mode: InsertMode, - pub if_generation_match: u32, + pub if_generation_match: u64, pub metadata: *const u8, pub metadata_len: u32, pub time_to_live_sec: u32, @@ -2602,9 +2602,10 @@ pub mod fastly_kv_store { pub struct InsertConfigOptions: u32 { const RESERVED = 1 << 0; const BACKGROUND_FETCH = 1 << 1; - const IF_GENERATION_MATCH = 1 << 2; + const RESERVED_2 = 1 << 2; const METADATA = 1 << 3; const TIME_TO_LIVE_SEC = 1 << 4; + const IF_GENERATION_MATCH = 1 << 5; } /// `ListConfigOptions` codings. #[derive(Default)] @@ -2791,6 +2792,63 @@ pub mod fastly_kv_store { } ); + let body = res.body(); + let generation = 0; + + unsafe { + *body_handle_out = body; + *generation_out = generation; + } + + FastlyStatus::OK + } + + #[export_name = "fastly_kv_store#lookup_wait_v2"] + pub fn lookup_wait_v2( + pending_handle: PendingObjectStoreLookupHandle, + body_handle_out: *mut BodyHandle, + metadata_out: *mut u8, + metadata_len: usize, + nwritten_out: *mut usize, + generation_out: *mut u64, + kv_error_out: *mut KvError, + ) -> FastlyStatus { + let res = match kv_store::lookup_wait(pending_handle) { + Ok((res, status)) => { + unsafe { + *kv_error_out = status.into(); + } + + let Some(res) = res else { + return FastlyStatus::OK; + }; + + res + } + Err(e) => { + unsafe { + *kv_error_out = KvError::Uninitialized; + } + + return e.into(); + } + }; + + with_buffer!( + metadata_out, + metadata_len, + { res.metadata(u64::try_from(metadata_len).trapping_unwrap()) }, + |res| { + let buf = handle_buffer_len!(res, nwritten_out); + + unsafe { + *nwritten_out = buf.as_ref().map(Vec::len).unwrap_or(0); + } + + std::mem::forget(buf); + } + ); + let body = res.body(); let generation = res.generation(); diff --git a/lib/compute-at-edge-abi/compute-at-edge.witx b/lib/compute-at-edge-abi/compute-at-edge.witx index b728d74e..76bcd1aa 100644 --- a/lib/compute-at-edge-abi/compute-at-edge.witx +++ b/lib/compute-at-edge-abi/compute-at-edge.witx @@ -878,6 +878,8 @@ (result $err (expected (error $fastly_status))) ) + ;; deprecated, generation always returns 0 + ;; via a failed u32::parse of a u64 (@interface func (export "lookup_wait") (param $handle $kv_store_lookup_handle) (param $body_handle_out (@witx pointer $body_handle)) @@ -889,6 +891,17 @@ (result $err (expected (error $fastly_status))) ) + (@interface func (export "lookup_wait_v2") + (param $handle $kv_store_lookup_handle) + (param $body_handle_out (@witx pointer $body_handle)) + (param $metadata_buf (@witx pointer (@witx char8))) + (param $metadata_buf_len (@witx usize)) + (param $nwritten_out (@witx pointer (@witx usize))) + (param $generation_out (@witx pointer u64)) + (param $kv_error_out (@witx pointer $kv_error)) + (result $err (expected (error $fastly_status))) + ) + (@interface func (export "insert") (param $store $kv_store_handle) (param $key string) diff --git a/lib/compute-at-edge-abi/typenames.witx b/lib/compute-at-edge-abi/typenames.witx index a8e18fba..ecd268c1 100644 --- a/lib/compute-at-edge-abi/typenames.witx +++ b/lib/compute-at-edge-abi/typenames.witx @@ -422,9 +422,11 @@ (flags (@witx repr u32) $reserved $background_fetch - $if_generation_match + ;; reserved_2 was previously if_generation_match (u32) + $reserved_2 $metadata $time_to_live_sec + $if_generation_match )) (typename $kv_insert_mode @@ -437,10 +439,11 @@ (typename $kv_insert_config (record (field $mode $kv_insert_mode) - (field $if_generation_match u32) + (field $unused u32) (field $metadata (@witx pointer (@witx char8))) (field $metadata_len u32) (field $time_to_live_sec u32) + (field $if_generation_match u64) )) (typename $kv_list_config_options diff --git a/lib/src/component/kv_store.rs b/lib/src/component/kv_store.rs index b67e0020..f0c7a071 100644 --- a/lib/src/component/kv_store.rs +++ b/lib/src/component/kv_store.rs @@ -22,7 +22,7 @@ use { pub struct LookupResult { body: http_body::BodyHandle, metadata: Option>, - generation: u32, + generation: u64, } #[async_trait::async_trait] @@ -54,7 +54,7 @@ impl kv_store::HostLookupResult for ComponentCtx { async fn generation( &mut self, rep: wasmtime::component::Resource, - ) -> wasmtime::Result { + ) -> wasmtime::Result { Ok(self.table().get(&rep)?.generation) } diff --git a/lib/src/object_store.rs b/lib/src/object_store.rs index 9696567f..6c9d873b 100644 --- a/lib/src/object_store.rs +++ b/lib/src/object_store.rs @@ -14,7 +14,7 @@ pub struct ObjectValue { pub body: Vec, pub metadata: Vec, pub metadata_len: usize, - pub generation: u32, + pub generation: u64, pub expiration: Option, } @@ -90,7 +90,7 @@ impl ObjectStores { obj_key: ObjectKey, obj: Vec, mode: KvInsertMode, - generation: Option, + generation: Option, metadata: Option>, ttl: Option, ) -> Result<(), KvStoreError> { @@ -153,7 +153,7 @@ impl ObjectStores { generation: SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) .unwrap() - .as_nanos() as u32, + .as_nanos() as u64, expiration: exp, }; diff --git a/lib/src/session.rs b/lib/src/session.rs index edade7fd..601c1033 100644 --- a/lib/src/session.rs +++ b/lib/src/session.rs @@ -700,7 +700,7 @@ impl Session { obj_key: ObjectKey, obj: Vec, mode: Option, - generation: Option, + generation: Option, metadata: Option>, ttl: Option, ) -> Result<(), KvStoreError> { diff --git a/lib/src/wiggle_abi.rs b/lib/src/wiggle_abi.rs index e191b0b1..c7f2c069 100644 --- a/lib/src/wiggle_abi.rs +++ b/lib/src/wiggle_abi.rs @@ -78,7 +78,7 @@ wiggle::from_witx!({ async: { fastly_async_io::{select}, fastly_object_store::{delete_async, pending_delete_wait, insert, insert_async, pending_insert_wait, lookup_async, pending_lookup_wait, list}, - fastly_kv_store::{lookup, lookup_wait, insert, insert_wait, delete, delete_wait, list, list_wait}, + fastly_kv_store::{lookup, lookup_wait, lookup_wait_v2, insert, insert_wait, delete, delete_wait, list, list_wait}, fastly_http_body::{append, read, write}, fastly_http_cache::{lookup, transaction_lookup, insert, transaction_insert, transaction_insert_and_stream_back, transaction_update, transaction_update_and_return_fresh, transaction_record_not_cacheable, transaction_abandon, found, close, get_suggested_backend_request, get_suggested_cache_options, prepare_response_for_storage, get_found_response, get_state, get_length, get_max_age_ns, get_stale_while_revalidate_ns, get_age_ns, get_hits, get_sensitive_data, get_surrogate_keys, get_vary_rule}, fastly_http_req::{ diff --git a/lib/src/wiggle_abi/kv_store_impl.rs b/lib/src/wiggle_abi/kv_store_impl.rs index 96f3ca0d..655bf02e 100644 --- a/lib/src/wiggle_abi/kv_store_impl.rs +++ b/lib/src/wiggle_abi/kv_store_impl.rs @@ -81,6 +81,57 @@ impl FastlyKvStore for Session { .recv() .await?; + match resp { + Ok(value) => { + let body_handle = self.insert_body(value.body.into()); + + memory.write(body_handle_out, body_handle)?; + match value.metadata_len { + 0 => memory.write(nwritten_out, 0)?, + len => { + let meta_len_u32 = + u32::try_from(len).expect("metadata len is outside the bounds of u32"); + memory.write(nwritten_out, meta_len_u32)?; + if meta_len_u32 > metadata_buf_len { + return Err(Error::BufferLengthError { + buf: "metadata", + len: "specified length", + }); + } + memory.copy_from_slice( + &value.metadata, + metadata_buf.as_array(meta_len_u32), + )?; + } + } + memory.write(generation_out, 0)?; + memory.write(kv_error_out, KvError::Ok)?; + Ok(()) + } + Err(e) => { + memory.write(kv_error_out, (&e).into())?; + Ok(()) + } + } + } + + async fn lookup_wait_v2( + &mut self, + memory: &mut GuestMemory<'_>, + pending_kv_lookup_handle: KvStoreLookupHandle, + body_handle_out: GuestPtr, + metadata_buf: GuestPtr, + metadata_buf_len: u32, + nwritten_out: GuestPtr, + generation_out: GuestPtr, + kv_error_out: GuestPtr, + ) -> Result<(), Error> { + let resp = self + .take_pending_kv_lookup(pending_kv_lookup_handle.into())? + .task() + .recv() + .await?; + match resp { Ok(value) => { let body_handle = self.insert_body(value.body.into()); diff --git a/lib/wit/deps/fastly/compute.wit b/lib/wit/deps/fastly/compute.wit index cc1076dc..e5f2342f 100644 --- a/lib/wit/deps/fastly/compute.wit +++ b/lib/wit/deps/fastly/compute.wit @@ -746,7 +746,7 @@ interface kv-store { resource lookup-result { body: func() -> body-handle; metadata: func(max-len: u64) -> result>, error>; - generation: func() -> u32; + generation: func() -> u64; } lookup-wait: func( @@ -770,7 +770,7 @@ interface kv-store { record insert-config { mode: insert-mode, - if-generation-match: u32, + if-generation-match: u64, metadata: list, time-to-live-sec: u32, } From ad2963d488ddc63029d1bb259a854b43b84e9e91 Mon Sep 17 00:00:00 2001 From: computermouth Date: Wed, 30 Oct 2024 14:33:52 -0600 Subject: [PATCH 2/2] update adapter wasm --- lib/data/viceroy-component-adapter.wasm | Bin 200935 -> 201382 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/lib/data/viceroy-component-adapter.wasm b/lib/data/viceroy-component-adapter.wasm index 57cfa86674316b58bacafc7b76ecbcae1d45a2cb..5493b851c3b3b1f093c8be5034db1556280a0233 100755 GIT binary patch delta 33804 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