diff --git a/include/proxy-wasm/wasm.h b/include/proxy-wasm/wasm.h index 23ed3c1da..1a785a8f9 100644 --- a/include/proxy-wasm/wasm.h +++ b/include/proxy-wasm/wasm.h @@ -337,6 +337,7 @@ class WasmHandleBase : public std::enable_shared_from_this { protected: std::shared_ptr wasm_base_; + std::unordered_map plugin_canary_cache_; }; std::string makeVmKey(std::string_view vm_id, std::string_view configuration, diff --git a/src/wasm.cc b/src/wasm.cc index 5519b3e77..a7a22fc9c 100644 --- a/src/wasm.cc +++ b/src/wasm.cc @@ -472,6 +472,10 @@ bool WasmHandleBase::canary(const std::shared_ptr &plugin, if (this->wasm() == nullptr) { return false; } + auto it = plugin_canary_cache_.find(plugin->key()); + if (it != plugin_canary_cache_.end()) { + return it->second; + } auto configuration_canary_handle = clone_factory(shared_from_this()); if (!configuration_canary_handle) { this->wasm()->fail(FailState::UnableToCloneVm, "Failed to clone Base Wasm"); @@ -490,9 +494,11 @@ bool WasmHandleBase::canary(const std::shared_ptr &plugin, if (!configuration_canary_handle->wasm()->configure(root_context, plugin)) { configuration_canary_handle->wasm()->fail(FailState::ConfigureFailed, "Failed to configure base Wasm plugin"); + plugin_canary_cache_[plugin->key()] = false; return false; } configuration_canary_handle->kill(); + plugin_canary_cache_[plugin->key()] = true; return true; } diff --git a/test/wasm_test.cc b/test/wasm_test.cc index ad0e16ac3..b88732698 100644 --- a/test/wasm_test.cc +++ b/test/wasm_test.cc @@ -172,6 +172,7 @@ TEST_P(TestVm, AlwaysApplyCanary) { // For each create Wasm, canary should be done. EXPECT_EQ(canary_count, 1); + bool first = true; std::unordered_set> reference_holder; for (const auto &root_id : root_ids) { @@ -196,8 +197,15 @@ TEST_P(TestVm, AlwaysApplyCanary) { auto wasm_handle_comp = createWasm(vm_key, source, plugin_comp, wasm_handle_factory_comp, wasm_handle_clone_factory_for_canary, false); - // For each create Wasm, canary should be done. - EXPECT_EQ(canary_count, 1); + // Validate that canarying is cached for the first baseline plugin variant. + if (first) { + first = false; + EXPECT_EQ(canary_count, 0); + } else { + // For each create Wasm, canary should be done. + EXPECT_EQ(canary_count, 1); + EXPECT_TRUE(TestContext::isGlobalLogged("onConfigure: " + root_id)); + } if (plugin_config.empty()) { // canary_check.wasm should raise the error at `onConfigure` in canary when the @@ -212,8 +220,6 @@ TEST_P(TestVm, AlwaysApplyCanary) { // destroyed for each iteration. reference_holder.insert(wasm_handle_comp); - EXPECT_TRUE(TestContext::isGlobalLogged("onConfigure: " + root_id)); - // Wasm VM is unique for vm_key. if (vm_key == vm_key_baseline) { EXPECT_EQ(wasm_handle_baseline->wasm(), wasm_handle_comp->wasm());