Skip to content

Commit 56204b1

Browse files
authored
Changes for integration into proxy-wasm. (proxy-wasm#8)
Signed-off-by: John Plevyak <[email protected]>
1 parent 3222ea6 commit 56204b1

File tree

14 files changed

+658
-392
lines changed

14 files changed

+658
-392
lines changed

.github/workflows/cpp.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ jobs:
5353
runs-on: ubuntu-latest
5454

5555
steps:
56-
- uses: actions/checkout@v1
56+
- uses: actions/checkout@v2
5757

5858
- name: Mount bazel cache
5959
uses: actions/cache@v1

BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ cc_library(
2222
copts = ["-DWITHOUT_ZLIB=1"],
2323
deps = [
2424
":include",
25+
"@com_google_protobuf//:protobuf_lite",
2526
"@proxy_wasm_cpp_sdk//:api_lib",
2627
],
2728
)
@@ -45,6 +46,7 @@ cc_library(
4546
"@com_google_absl//absl/base",
4647
"@com_google_absl//absl/strings",
4748
"@com_google_absl//absl/types:optional",
49+
"@com_google_protobuf//:protobuf_lite",
4850
"@proxy_wasm_cpp_sdk//:api_lib",
4951
],
5052
)

WORKSPACE

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,10 @@ workspace(name = "proxy_wasm_cpp_host")
33
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
44
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
55

6-
http_archive(
6+
git_repository(
77
name = "proxy_wasm_cpp_sdk",
8-
sha256 = "14f66f67e8f37ec81d28d7f5307be4407d206ac5f0daaf6d22fa5536797bcac1",
9-
strip_prefix = "proxy-wasm-cpp-sdk-31f1fc5b7e09f231fa532d2d296e479a113c3e10",
10-
urls = ["https://github.com/proxy-wasm/proxy-wasm-cpp-sdk/archive/31f1fc5b7e09f231fa532d2d296e479a113c3e10.tar.gz"],
11-
patch_cmds = ["rm BUILD"],
12-
build_file = '//bazel/external:proxy-wasm-cpp-sdk.BUILD',
8+
remote = "https://github.com/proxy-wasm/proxy-wasm-cpp-sdk",
9+
commit = "c12553951d01bb60cb1448ba1fcfeb8f843aad62",
1310
)
1411

1512
http_archive(
@@ -20,7 +17,6 @@ http_archive(
2017
urls = ["https://github.com/abseil/abseil-cpp/archive/37dd2562ec830d547a1524bb306be313ac3f2556.tar.gz"],
2118
)
2219

23-
2420
# required by com_google_protobuf
2521
http_archive(
2622
name = "bazel_skylib",

include/proxy-wasm/context.h

Lines changed: 43 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ class WasmVm;
3636

3737
using Pairs = std::vector<std::pair<string_view, string_view>>;
3838
using PairsWithStringValues = std::vector<std::pair<string_view, std::string>>;
39-
using CallOnThreadFunction = std::function<void(std::function<void()>)>;
4039

4140
struct BufferInterface {
4241
virtual ~BufferInterface() {}
@@ -50,9 +49,12 @@ struct BufferInterface {
5049
* @param size_ptr is the location in the VM address space to place the size of the newly
5150
* allocated memory block which contains the copied bytes (e.g. length).
5251
* @return true on success.
52+
* Length is guarantteed to be > 0 and the bounds have already been checked.
5353
*/
54-
virtual bool copyTo(WasmBase *wasm, size_t start, size_t length, uint64_t ptr_ptr,
55-
uint64_t size_ptr) const = 0;
54+
virtual WasmResult copyTo(WasmBase *wasm, size_t start, size_t length, uint64_t ptr_ptr,
55+
uint64_t size_ptr) const = 0;
56+
57+
virtual WasmResult copyFrom(size_t start, size_t length, string_view data) = 0;
5658
};
5759

5860
// Opaque context object.
@@ -94,7 +96,7 @@ class ContextBase {
9496
uint32_t id() const { return id_; }
9597
bool isVmContext() const { return id_ == 0; }
9698
bool isRootContext() const { return root_context_id_ == 0; }
97-
ContextBase *root_context() { return root_context_; }
99+
ContextBase *root_context() const { return root_context_; }
98100
string_view root_id() const { return isRootContext() ? root_id_ : plugin_->root_id_; }
99101
string_view log_prefix() const {
100102
return isRootContext() ? root_log_prefix_ : plugin_->log_prefix();
@@ -104,76 +106,50 @@ class ContextBase {
104106
// Called before deleting the context.
105107
virtual void destroy();
106108

107-
//
108109
// VM level downcalls into the WASM code on Context(id == 0).
109-
//
110110
virtual bool onStart(std::shared_ptr<PluginBase> plugin);
111111
virtual bool onConfigure(std::shared_ptr<PluginBase> plugin);
112112

113-
//
113+
// Root Context downcalls into the WASM code Context(id != 0, root_context_id_ == 0);
114+
virtual void onTick();
115+
114116
// Stream downcalls on Context(id > 0).
115117
//
116118
// General stream downcall on a new stream.
117119
virtual void onCreate(uint32_t root_context_id);
120+
118121
// Network
119-
virtual FilterStatus onNetworkNewConnection() {
120-
unimplemented();
121-
return FilterStatus::Continue;
122-
}
123-
virtual FilterStatus onDownstreamData(int /* data_length */, bool /* end_of_stream */) {
124-
unimplemented();
125-
return FilterStatus::Continue;
126-
}
127-
virtual FilterStatus onUpstreamData(int /* data_length */, bool /* end_of_stream */) {
128-
unimplemented();
129-
return FilterStatus::Continue;
130-
}
122+
virtual FilterStatus onNetworkNewConnection();
123+
virtual FilterStatus onDownstreamData(int data_length, bool end_of_stream);
124+
virtual FilterStatus onUpstreamData(int data_length, bool end_of_stream);
131125
enum class PeerType : uint32_t {
132126
Unknown = 0,
133127
Local = 1,
134128
Remote = 2,
135129
};
136-
virtual void onDownstreamConnectionClose(PeerType) { unimplemented(); }
137-
virtual void onUpstreamConnectionClose(PeerType) { unimplemented(); }
130+
virtual void onDownstreamConnectionClose(PeerType);
131+
virtual void onUpstreamConnectionClose(PeerType);
138132
// HTTP Filter Stream Request Downcalls.
139-
virtual FilterHeadersStatus onRequestHeaders() {
140-
unimplemented();
141-
return FilterHeadersStatus::Continue;
142-
}
143-
virtual FilterDataStatus onRequestBody(int /* body_buffer_length */, bool /* end_of_stream */) {
144-
unimplemented();
145-
return FilterDataStatus::Continue;
146-
}
147-
virtual FilterTrailersStatus onRequestTrailers() {
148-
unimplemented();
149-
return FilterTrailersStatus::Continue;
150-
}
151-
virtual FilterMetadataStatus onRequestMetadata() {
152-
unimplemented();
153-
return FilterMetadataStatus::Continue;
154-
}
133+
virtual FilterHeadersStatus onRequestHeaders(uint32_t headers);
134+
virtual FilterDataStatus onRequestBody(uint32_t body_buffer_length, bool end_of_stream);
135+
virtual FilterTrailersStatus onRequestTrailers(uint32_t trailers);
136+
virtual FilterMetadataStatus onRequestMetadata(uint32_t elements);
155137
// HTTP Filter Stream Response Downcalls.
156-
virtual FilterHeadersStatus onResponseHeaders() {
157-
unimplemented();
158-
return FilterHeadersStatus::Continue;
159-
}
160-
virtual FilterDataStatus onResponseBody(int /* body_buffer_length */, bool /* end_of_stream */) {
161-
unimplemented();
162-
return FilterDataStatus::Continue;
163-
}
164-
virtual FilterTrailersStatus onResponseTrailers() {
165-
unimplemented();
166-
return FilterTrailersStatus::Continue;
167-
}
168-
virtual FilterMetadataStatus onResponseMetadata() {
169-
unimplemented();
170-
return FilterMetadataStatus::Continue;
171-
}
138+
virtual FilterHeadersStatus onResponseHeaders(uint32_t headers);
139+
virtual FilterDataStatus onResponseBody(uint32_t body_buffer_length, bool end_of_stream);
140+
virtual FilterTrailersStatus onResponseTrailers(uint32_t trailers);
141+
virtual FilterMetadataStatus onResponseMetadata(uint32_t elements);
172142
// Async call response.
173-
virtual void onHttpCallResponse(uint32_t /* token */, uint32_t /* headers */,
174-
uint32_t /* body_size */, uint32_t /* trailers */) {}
143+
virtual void onHttpCallResponse(uint32_t token, uint32_t headers, uint32_t body_size,
144+
uint32_t trailers);
145+
// Grpc
146+
virtual void onGrpcReceiveInitialMetadata(uint32_t token, uint32_t elements);
147+
virtual void onGrpcReceiveTrailingMetadata(uint32_t token, uint32_t trailers);
148+
virtual void onGrpcReceive(uint32_t token, uint32_t response_size);
149+
virtual void onGrpcClose(uint32_t token, uint32_t status_code);
150+
175151
// Inter-VM shared queue message arrival.
176-
virtual void onQueueReady(uint32_t /* token */) { unimplemented(); }
152+
virtual void onQueueReady(uint32_t /* token */);
177153
// General stream downcall when the stream/vm has ended.
178154
virtual bool onDone();
179155
// General stream downcall for logging. Occurs after onDone().
@@ -212,7 +188,7 @@ class ContextBase {
212188
}
213189

214190
// Buffer
215-
virtual const BufferInterface *getBuffer(WasmBufferType /* type */) {
191+
virtual BufferInterface *getBuffer(WasmBufferType /* type */) {
216192
unimplemented();
217193
return nullptr;
218194
}
@@ -233,14 +209,16 @@ class ContextBase {
233209
// gRPC
234210
// Returns a token which will be used with the corresponding onGrpc and grpc calls.
235211
virtual WasmResult grpcCall(string_view /* grpc_service */, string_view /* service_name */,
236-
string_view /* method_name */, string_view /* request */,
212+
string_view /* method_name */, const Pairs & /* initial_metadata */,
213+
string_view /* request */,
237214
const optional<std::chrono::milliseconds> & /* timeout */,
238215
uint32_t * /* token_ptr */) {
239216
unimplemented();
240217
return WasmResult::Unimplemented;
241218
}
242219
virtual WasmResult grpcStream(string_view /* grpc_service */, string_view /* service_name */,
243-
string_view /* method_name */, uint32_t * /* token_ptr */) {
220+
string_view /* method_name */, const Pairs & /* initial_metadata */,
221+
uint32_t * /* token_ptr */) {
244222
unimplemented();
245223
return WasmResult::Unimplemented;
246224
}
@@ -342,7 +320,12 @@ class ContextBase {
342320
protected:
343321
friend class WasmBase;
344322

345-
virtual void initializeRoot(WasmBase *wasm, std::shared_ptr<PluginBase> plugin);
323+
// NB: initializeRootBase is non-virtual and can be called in the constructor without ambiguity.
324+
void initializeRootBase(WasmBase *wasm, std::shared_ptr<PluginBase> plugin);
325+
// NB: initializeRoot is virtual and should be called only outside of the constructor.
326+
virtual void initializeRoot(WasmBase *wasm, std::shared_ptr<PluginBase> plugin) {
327+
initializeRootBase(wasm, plugin);
328+
}
346329
std::string makeRootLogPrefix(string_view vm_id) const;
347330

348331
WasmBase *wasm_{nullptr};

include/proxy-wasm/exports.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ Word enqueue_shared_queue(void *raw_context, Word token, Word data_ptr, Word dat
4848
Word get_buffer_bytes(void *raw_context, Word type, Word start, Word length, Word ptr_ptr,
4949
Word size_ptr);
5050
Word get_buffer_status(void *raw_context, Word type, Word length_ptr, Word flags_ptr);
51+
Word set_buffer_bytes(void *raw_context, Word type, Word start, Word length, Word data_ptr,
52+
Word data_size);
5153
Word add_header_map_value(void *raw_context, Word type, Word key_ptr, Word key_size, Word value_ptr,
5254
Word value_size);
5355
Word get_header_map_value(void *raw_context, Word type, Word key_ptr, Word key_size,
@@ -72,10 +74,11 @@ Word record_metric(void *raw_context, Word metric_id, uint64_t value);
7274
Word get_metric(void *raw_context, Word metric_id, Word result_uint64_ptr);
7375
Word grpc_call(void *raw_context, Word service_ptr, Word service_size, Word service_name_ptr,
7476
Word service_name_size, Word method_name_ptr, Word method_name_size,
75-
Word request_ptr, Word request_size, Word timeout_milliseconds, Word token_ptr);
77+
Word initial_metadata_ptr, Word initial_metadata_size, Word request_ptr,
78+
Word request_size, Word timeout_milliseconds, Word token_ptr);
7679
Word grpc_stream(void *raw_context, Word service_ptr, Word service_size, Word service_name_ptr,
7780
Word service_name_size, Word method_name_ptr, Word method_name_size,
78-
Word token_ptr);
81+
Word initial_metadata_ptr, Word initial_metadata_size, Word token_ptr);
7982
Word grpc_cancel(void *raw_context, Word token);
8083
Word grpc_close(void *raw_context, Word token);
8184
Word grpc_send(void *raw_context, Word token, Word message_ptr, Word message_size, Word end_stream);
@@ -92,8 +95,10 @@ Word call_foreign_function(void *raw_context, Word function_name, Word function_
9295

9396
Word wasi_unstable_fd_write(void *raw_context, Word fd, Word iovs, Word iovs_len,
9497
Word nwritten_ptr);
98+
Word wasi_unstable_fd_read(void *, Word, Word, Word, Word);
9599
Word wasi_unstable_fd_seek(void *, Word, int64_t, Word, Word);
96100
Word wasi_unstable_fd_close(void *, Word);
101+
Word wasi_unstable_fd_fdstat_get(void *, Word fd, Word statOut);
97102
Word wasi_unstable_environ_get(void *, Word, Word);
98103
Word wasi_unstable_environ_sizes_get(void *raw_context, Word count_ptr, Word buf_size_ptr);
99104
Word wasi_unstable_args_get(void *raw_context, Word argc_ptr, Word argv_buf_size_ptr);

include/proxy-wasm/null_plugin.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ class NullPlugin : public NullVmPlugin {
9999

100100
void onGrpcReceive(uint64_t context_id, uint64_t token, size_t body_size);
101101
void onGrpcClose(uint64_t context_id, uint64_t token, uint64_t status_code);
102-
void onGrpcCreateInitialMetadata(uint64_t context_id, uint64_t token, uint64_t headers);
103102
void onGrpcReceiveInitialMetadata(uint64_t context_id, uint64_t token, uint64_t headers);
104103
void onGrpcReceiveTrailingMetadata(uint64_t context_id, uint64_t token, uint64_t trailers);
105104

include/proxy-wasm/wasm.h

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,21 @@ namespace proxy_wasm {
3434

3535
#include "proxy_wasm_common.h"
3636

37+
class ContextBase;
3738
class WasmBase;
38-
class WasmHandle;
39+
class WasmHandleBase;
3940

4041
using WasmForeignFunction =
4142
std::function<WasmResult(WasmBase &, string_view, std::function<void *(size_t size)>)>;
4243
using WasmVmFactory = std::function<std::unique_ptr<WasmVm>()>;
44+
using CallOnThreadFunction = std::function<void(std::function<void()>)>;
4345

4446
// Wasm execution instance. Manages the host side of the Wasm interface.
4547
class WasmBase : public std::enable_shared_from_this<WasmBase> {
4648
public:
4749
WasmBase(std::unique_ptr<WasmVm> wasm_vm, string_view vm_id, string_view vm_configuration,
4850
string_view vm_key);
49-
WasmBase(const std::shared_ptr<WasmHandle> &other, WasmVmFactory factory);
51+
WasmBase(const std::shared_ptr<WasmHandleBase> &other, WasmVmFactory factory);
5052
virtual ~WasmBase();
5153

5254
bool initialize(const std::string &code, bool allow_precompiled = false);
@@ -78,11 +80,17 @@ class WasmBase : public std::enable_shared_from_this<WasmBase> {
7880
unimplemented();
7981
return nullptr;
8082
}
83+
// NB: if plugin is nullptr, then a VM Context is returned.
84+
virtual ContextBase *createContext(std::shared_ptr<PluginBase> plugin) {
85+
if (plugin)
86+
return new ContextBase(this, plugin);
87+
return new ContextBase(this);
88+
}
8189

82-
void setTickPeriod(uint32_t /* root_context_id */, std::chrono::milliseconds /* tick_period */) {
83-
unimplemented();
90+
virtual void setTickPeriod(uint32_t root_context_id, std::chrono::milliseconds tick_period) {
91+
tick_period_[root_context_id] = tick_period;
8492
}
85-
void tickHandler(uint32_t /* root_context_idl */) { unimplemented(); }
93+
void tick(uint32_t root_context_id);
8694
void queueReady(uint32_t root_context_id, uint32_t token);
8795

8896
void startShutdown();
@@ -216,7 +224,7 @@ class WasmBase : public std::enable_shared_from_this<WasmBase> {
216224
WasmCallVoid<1> on_log_;
217225
WasmCallVoid<1> on_delete_;
218226

219-
std::shared_ptr<WasmHandle> base_wasm_handle_;
227+
std::shared_ptr<WasmHandleBase> base_wasm_handle_;
220228

221229
// Used by the base_wasm to enable non-clonable thread local Wasm(s) to be constructed.
222230
std::string code_;
@@ -235,43 +243,40 @@ class WasmBase : public std::enable_shared_from_this<WasmBase> {
235243
uint32_t next_gauge_metric_id_ = static_cast<uint32_t>(MetricType::Gauge);
236244
uint32_t next_histogram_metric_id_ = static_cast<uint32_t>(MetricType::Histogram);
237245

238-
// Foreign Functions.
239-
std::unordered_map<std::string, WasmForeignFunction> foreign_functions_;
240-
241246
// Actions to be done after the call into the VM returns.
242247
std::deque<std::function<void()>> after_vm_call_actions_;
243248
};
244249

245250
// Handle which enables shutdown operations to run post deletion (e.g. post listener drain).
246-
class WasmHandle : public std::enable_shared_from_this<WasmHandle> {
251+
class WasmHandleBase : public std::enable_shared_from_this<WasmHandleBase> {
247252
public:
248-
explicit WasmHandle(std::shared_ptr<WasmBase> wasm) : wasm_(wasm) {}
249-
~WasmHandle() { wasm_->startShutdown(); }
253+
explicit WasmHandleBase(std::shared_ptr<WasmBase> wasm_base) : wasm_base_(wasm_base) {}
254+
~WasmHandleBase() { wasm_base_->startShutdown(); }
250255

251-
std::shared_ptr<WasmBase> &wasm() { return wasm_; }
256+
std::shared_ptr<WasmBase> &wasm() { return wasm_base_; }
252257

253-
private:
254-
std::shared_ptr<WasmBase> wasm_;
258+
protected:
259+
std::shared_ptr<WasmBase> wasm_base_;
255260
};
256261

257262
std::string makeVmKey(string_view vm_id, string_view configuration, string_view code);
258263

259-
using WasmHandleFactory = std::function<std::shared_ptr<WasmHandle>(string_view vm_id)>;
264+
using WasmHandleFactory = std::function<std::shared_ptr<WasmHandleBase>(string_view vm_id)>;
260265
using WasmHandleCloneFactory =
261-
std::function<std::shared_ptr<WasmHandle>(std::shared_ptr<WasmHandle> wasm)>;
266+
std::function<std::shared_ptr<WasmHandleBase>(std::shared_ptr<WasmHandleBase> wasm)>;
262267

263268
// Returns nullptr on failure (i.e. initialization of the VM fails).
264-
std::shared_ptr<WasmHandle>
269+
std::shared_ptr<WasmHandleBase>
265270
createWasm(std::string vm_key, std::string code, std::shared_ptr<PluginBase> plugin,
266271
WasmHandleFactory factory, bool allow_precompiled,
267272
std::unique_ptr<ContextBase> root_context_for_testing = nullptr);
268273
// Get an existing ThreadLocal VM matching 'vm_id' or nullptr if there isn't one.
269-
std::shared_ptr<WasmHandle> getThreadLocalWasm(string_view vm_id);
274+
std::shared_ptr<WasmHandleBase> getThreadLocalWasm(string_view vm_id);
270275
// Get an existing ThreadLocal VM matching 'vm_id' or create one using 'base_wavm' by cloning or by
271276
// using it it as a template.
272-
std::shared_ptr<WasmHandle> getOrCreateThreadLocalWasm(std::shared_ptr<WasmHandle> &base_wasm,
273-
std::shared_ptr<PluginBase> plugin,
274-
WasmHandleCloneFactory factory);
277+
std::shared_ptr<WasmHandleBase>
278+
getOrCreateThreadLocalWasm(std::shared_ptr<WasmHandleBase> base_wasm,
279+
std::shared_ptr<PluginBase> plugin, WasmHandleCloneFactory factory);
275280

276281
inline const std::string &WasmBase::vm_configuration() const {
277282
if (base_wasm_handle_)

0 commit comments

Comments
 (0)