/proc/self/cwd/source/extensions/common/wasm/wasm.h
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | |
3 | | #include <atomic> |
4 | | #include <chrono> |
5 | | #include <map> |
6 | | #include <memory> |
7 | | |
8 | | #include "envoy/common/exception.h" |
9 | | #include "envoy/extensions/wasm/v3/wasm.pb.validate.h" |
10 | | #include "envoy/http/filter.h" |
11 | | #include "envoy/server/lifecycle_notifier.h" |
12 | | #include "envoy/stats/scope.h" |
13 | | #include "envoy/stats/stats.h" |
14 | | #include "envoy/thread_local/thread_local_object.h" |
15 | | #include "envoy/upstream/cluster_manager.h" |
16 | | |
17 | | #include "source/common/common/assert.h" |
18 | | #include "source/common/common/logger.h" |
19 | | #include "source/common/config/datasource.h" |
20 | | #include "source/common/stats/symbol_table.h" |
21 | | #include "source/common/version/version.h" |
22 | | #include "source/extensions/common/wasm/context.h" |
23 | | #include "source/extensions/common/wasm/plugin.h" |
24 | | #include "source/extensions/common/wasm/remote_async_datasource.h" |
25 | | #include "source/extensions/common/wasm/stats_handler.h" |
26 | | #include "source/extensions/common/wasm/wasm_vm.h" |
27 | | |
28 | | #include "include/proxy-wasm/exports.h" |
29 | | #include "include/proxy-wasm/wasm.h" |
30 | | |
31 | | namespace Envoy { |
32 | | namespace Extensions { |
33 | | namespace Common { |
34 | | namespace Wasm { |
35 | | |
36 | | using CreateContextFn = |
37 | | std::function<ContextBase*(Wasm* wasm, const std::shared_ptr<Plugin>& plugin)>; |
38 | | |
39 | | class WasmHandle; |
40 | | |
41 | | // Wasm execution instance. Manages the Envoy side of the Wasm interface. |
42 | | class Wasm : public WasmBase, Logger::Loggable<Logger::Id::wasm> { |
43 | | public: |
44 | | Wasm(WasmConfig& config, absl::string_view vm_key, const Stats::ScopeSharedPtr& scope, |
45 | | Api::Api& api, Upstream::ClusterManager& cluster_manager, Event::Dispatcher& dispatcher); |
46 | | Wasm(std::shared_ptr<WasmHandle> other, Event::Dispatcher& dispatcher); |
47 | | ~Wasm() override; |
48 | | |
49 | 0 | Upstream::ClusterManager& clusterManager() const { return cluster_manager_; } |
50 | 0 | Event::Dispatcher& dispatcher() { return dispatcher_; } |
51 | 0 | Api::Api& api() { return api_; } |
52 | 0 | Context* getRootContext(const std::shared_ptr<PluginBase>& plugin, bool allow_closed) { |
53 | 0 | return static_cast<Context*>(WasmBase::getRootContext(plugin, allow_closed)); |
54 | 0 | } |
55 | | void setTimerPeriod(uint32_t root_context_id, std::chrono::milliseconds period) override; |
56 | | virtual void tickHandler(uint32_t root_context_id); |
57 | 0 | std::shared_ptr<Wasm> sharedThis() { return std::static_pointer_cast<Wasm>(shared_from_this()); } |
58 | 0 | Network::DnsResolverSharedPtr& dnsResolver() { return dns_resolver_; } |
59 | | |
60 | | // WasmBase |
61 | | void error(std::string_view message) override; |
62 | | proxy_wasm::CallOnThreadFunction callOnThreadFunction() override; |
63 | | ContextBase* createContext(const std::shared_ptr<PluginBase>& plugin) override; |
64 | | ContextBase* createRootContext(const std::shared_ptr<PluginBase>& plugin) override; |
65 | | ContextBase* createVmContext() override; |
66 | | void registerCallbacks() override; |
67 | | void getFunctions() override; |
68 | | |
69 | | // AccessLog::Instance |
70 | | void log(const PluginSharedPtr& plugin, const Formatter::HttpFormatterContext& log_context, |
71 | | const StreamInfo::StreamInfo& info); |
72 | | |
73 | | void onStatsUpdate(const PluginSharedPtr& plugin, Envoy::Stats::MetricSnapshot& snapshot); |
74 | | |
75 | 0 | virtual std::string buildVersion() { return BUILD_VERSION_NUMBER; } |
76 | | |
77 | | void initializeLifecycle(Server::ServerLifecycleNotifier& lifecycle_notifier); |
78 | 0 | uint32_t nextDnsToken() { |
79 | 0 | do { |
80 | 0 | dns_token_++; |
81 | 0 | } while (!dns_token_); |
82 | 0 | return dns_token_; |
83 | 0 | } |
84 | | |
85 | | void setCreateContextForTesting(CreateContextFn create_context, |
86 | 0 | CreateContextFn create_root_context) { |
87 | 0 | create_context_for_testing_ = create_context; |
88 | 0 | create_root_context_for_testing_ = create_root_context; |
89 | 0 | } |
90 | 0 | void setFailStateForTesting(proxy_wasm::FailState fail_state) { failed_ = fail_state; } |
91 | | |
92 | | protected: |
93 | | friend class Context; |
94 | | |
95 | | void initializeStats(); |
96 | | // Calls into the VM. |
97 | | proxy_wasm::WasmCallVoid<3> on_resolve_dns_; |
98 | | proxy_wasm::WasmCallVoid<2> on_stats_update_; |
99 | | |
100 | | Stats::ScopeSharedPtr scope_; |
101 | | Api::Api& api_; |
102 | | Stats::StatNamePool stat_name_pool_; |
103 | | const Stats::StatName custom_stat_namespace_; |
104 | | Upstream::ClusterManager& cluster_manager_; |
105 | | Event::Dispatcher& dispatcher_; |
106 | | Event::PostCb server_shutdown_post_cb_; |
107 | | absl::flat_hash_map<uint32_t, Event::TimerPtr> timer_; // per root_id. |
108 | | TimeSource& time_source_; |
109 | | |
110 | | // Lifecycle stats |
111 | | LifecycleStatsHandler lifecycle_stats_handler_; |
112 | | |
113 | | // Plugin stats |
114 | | absl::flat_hash_map<uint32_t, Stats::Counter*> counters_; |
115 | | absl::flat_hash_map<uint32_t, Stats::Gauge*> gauges_; |
116 | | absl::flat_hash_map<uint32_t, Stats::Histogram*> histograms_; |
117 | | |
118 | | CreateContextFn create_context_for_testing_; |
119 | | CreateContextFn create_root_context_for_testing_; |
120 | | Network::DnsResolverSharedPtr dns_resolver_; |
121 | | uint32_t dns_token_ = 1; |
122 | | }; |
123 | | using WasmSharedPtr = std::shared_ptr<Wasm>; |
124 | | |
125 | | class WasmHandle : public WasmHandleBase, public ThreadLocal::ThreadLocalObject { |
126 | | public: |
127 | | explicit WasmHandle(const WasmSharedPtr& wasm) |
128 | 1 | : WasmHandleBase(std::static_pointer_cast<WasmBase>(wasm)), wasm_(wasm) {} |
129 | | |
130 | 0 | WasmSharedPtr& wasm() { return wasm_; } |
131 | | |
132 | | private: |
133 | | WasmSharedPtr wasm_; |
134 | | }; |
135 | | |
136 | | using WasmHandleSharedPtr = std::shared_ptr<WasmHandle>; |
137 | | |
138 | | class PluginHandle : public PluginHandleBase { |
139 | | public: |
140 | | explicit PluginHandle(const WasmHandleSharedPtr& wasm_handle, const PluginSharedPtr& plugin) |
141 | | : PluginHandleBase(std::static_pointer_cast<WasmHandleBase>(wasm_handle), |
142 | | std::static_pointer_cast<PluginBase>(plugin)), |
143 | 11 | plugin_(plugin), wasm_handle_(wasm_handle) {} |
144 | | |
145 | 0 | WasmHandleSharedPtr& wasmHandle() { return wasm_handle_; } |
146 | 0 | uint32_t rootContextId() { return wasm_handle_->wasm()->getRootContext(plugin_, false)->id(); } |
147 | | |
148 | | private: |
149 | | PluginSharedPtr plugin_; |
150 | | WasmHandleSharedPtr wasm_handle_; |
151 | | }; |
152 | | |
153 | | using PluginHandleSharedPtr = std::shared_ptr<PluginHandle>; |
154 | | |
155 | | class PluginHandleSharedPtrThreadLocal : public ThreadLocal::ThreadLocalObject { |
156 | | public: |
157 | 11 | PluginHandleSharedPtrThreadLocal(PluginHandleSharedPtr handle) : handle_(handle){}; |
158 | 0 | PluginHandleSharedPtr& handle() { return handle_; } |
159 | | |
160 | | private: |
161 | | PluginHandleSharedPtr handle_; |
162 | | }; |
163 | | |
164 | | using CreateWasmCallback = std::function<void(WasmHandleSharedPtr)>; |
165 | | |
166 | | // Returns false if createWasm failed synchronously. This is necessary because xDS *MUST* report |
167 | | // all failures synchronously as it has no facility to report configuration update failures |
168 | | // asynchronously. Callers should throw an exception if they are part of a synchronous xDS update |
169 | | // because that is the mechanism for reporting configuration errors. |
170 | | bool createWasm(const PluginSharedPtr& plugin, const Stats::ScopeSharedPtr& scope, |
171 | | Upstream::ClusterManager& cluster_manager, Init::Manager& init_manager, |
172 | | Event::Dispatcher& dispatcher, Api::Api& api, |
173 | | Envoy::Server::ServerLifecycleNotifier& lifecycle_notifier, |
174 | | RemoteAsyncDataProviderPtr& remote_data_provider, CreateWasmCallback&& callback, |
175 | | CreateContextFn create_root_context_for_testing = nullptr); |
176 | | |
177 | | PluginHandleSharedPtr |
178 | | getOrCreateThreadLocalPlugin(const WasmHandleSharedPtr& base_wasm, const PluginSharedPtr& plugin, |
179 | | Event::Dispatcher& dispatcher, |
180 | | CreateContextFn create_root_context_for_testing = nullptr); |
181 | | |
182 | | void clearCodeCacheForTesting(); |
183 | | void setTimeOffsetForCodeCacheForTesting(MonotonicTime::duration d); |
184 | | WasmEvent toWasmEvent(const std::shared_ptr<WasmHandleBase>& wasm); |
185 | | |
186 | | } // namespace Wasm |
187 | | } // namespace Common |
188 | | } // namespace Extensions |
189 | | } // namespace Envoy |