Skip to content

Commit 64313a6

Browse files
authored
Revert "Allow execution of multiple instances of the same plugin. (proxy-wasm#78)" (proxy-wasm#91)
This reverts commit f08baac. Signed-off-by: Piotr Sikora <[email protected]>
1 parent 31f3184 commit 64313a6

File tree

4 files changed

+71
-86
lines changed

4 files changed

+71
-86
lines changed

include/proxy-wasm/context.h

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,23 +50,20 @@ struct PluginBase {
5050
std::string_view runtime, std::string_view plugin_configuration, bool fail_open)
5151
: name_(std::string(name)), root_id_(std::string(root_id)), vm_id_(std::string(vm_id)),
5252
runtime_(std::string(runtime)), plugin_configuration_(plugin_configuration),
53-
fail_open_(fail_open), key_(root_id_ + "||" + plugin_configuration_) {}
53+
fail_open_(fail_open) {}
5454

5555
const std::string name_;
5656
const std::string root_id_;
5757
const std::string vm_id_;
5858
const std::string runtime_;
59-
const std::string plugin_configuration_;
59+
std::string plugin_configuration_;
6060
const bool fail_open_;
61-
62-
const std::string &key() const { return key_; }
6361
const std::string &log_prefix() const { return log_prefix_; }
6462

6563
private:
6664
std::string makeLogPrefix() const;
6765

68-
const std::string key_;
69-
const std::string log_prefix_;
66+
std::string log_prefix_;
7067
};
7168

7269
struct BufferBase : public BufferInterface {
@@ -376,16 +373,16 @@ class ContextBase : public RootInterface,
376373
protected:
377374
friend class WasmBase;
378375

376+
void initializeRootBase(WasmBase *wasm, std::shared_ptr<PluginBase> plugin);
379377
std::string makeRootLogPrefix(std::string_view vm_id) const;
380378

381379
WasmBase *wasm_{nullptr};
382380
uint32_t id_{0};
383-
uint32_t parent_context_id_{0}; // 0 for roots and the general context.
384-
ContextBase *parent_context_{nullptr}; // set in all contexts.
385-
std::string root_id_; // set only in root context.
386-
std::string root_log_prefix_; // set only in root context.
387-
std::shared_ptr<PluginBase> plugin_; // set in root and stream contexts.
388-
std::shared_ptr<PluginBase> temp_plugin_; // Remove once ABI v0.1.0 is gone.
381+
uint32_t parent_context_id_{0}; // 0 for roots and the general context.
382+
ContextBase *parent_context_{nullptr}; // set in all contexts.
383+
std::string root_id_; // set only in root context.
384+
std::string root_log_prefix_; // set only in root context.
385+
std::shared_ptr<PluginBase> plugin_;
389386
bool in_vm_context_created_ = false;
390387
bool destroyed_ = false;
391388
};

include/proxy-wasm/wasm.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ class WasmBase : public std::enable_shared_from_this<WasmBase> {
5959
std::string_view vm_key() const { return vm_key_; }
6060
WasmVm *wasm_vm() const { return wasm_vm_.get(); }
6161
ContextBase *vm_context() const { return vm_context_.get(); }
62-
ContextBase *getRootContext(const std::shared_ptr<PluginBase> &plugin, bool allow_closed);
62+
ContextBase *getRootContext(std::string_view root_id);
63+
ContextBase *getOrCreateRootContext(const std::shared_ptr<PluginBase> &plugin);
6364
ContextBase *getContext(uint32_t id) {
6465
auto it = contexts_.find(id);
6566
if (it != contexts_.end())
@@ -77,7 +78,6 @@ class WasmBase : public std::enable_shared_from_this<WasmBase> {
7778
void timerReady(uint32_t root_context_id);
7879
void queueReady(uint32_t root_context_id, uint32_t token);
7980

80-
void startShutdown(const std::shared_ptr<PluginBase> &plugin);
8181
void startShutdown();
8282
WasmResult done(ContextBase *root_context);
8383
void finishShutdown();
@@ -164,12 +164,11 @@ class WasmBase : public std::enable_shared_from_this<WasmBase> {
164164
uint32_t next_context_id_ = 1; // 0 is reserved for the VM context.
165165
std::shared_ptr<ContextBase> vm_context_; // Context unrelated to any specific root or stream
166166
// (e.g. for global constructors).
167-
std::unordered_map<std::string, std::unique_ptr<ContextBase>> root_contexts_; // Root contexts.
168-
std::unordered_map<std::string, std::unique_ptr<ContextBase>> pending_done_; // Root contexts.
169-
std::unordered_set<std::unique_ptr<ContextBase>> pending_delete_; // Root contexts.
167+
std::unordered_map<std::string, std::unique_ptr<ContextBase>> root_contexts_;
170168
std::unordered_map<uint32_t, ContextBase *> contexts_; // Contains all contexts.
171169
std::unordered_map<uint32_t, std::chrono::milliseconds> timer_period_; // per root_id.
172170
std::unique_ptr<ShutdownHandle> shutdown_handle_;
171+
std::unordered_set<ContextBase *> pending_done_; // Root contexts not done during shutdown.
173172

174173
WasmCallVoid<0> _initialize_; /* Emscripten v1.39.17+ */
175174
WasmCallVoid<0> _start_; /* Emscripten v1.39.0+ */

src/context.cc

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -269,10 +269,8 @@ ContextBase::ContextBase(WasmBase *wasm) : wasm_(wasm), parent_context_(this) {
269269
wasm_->contexts_[id_] = this;
270270
}
271271

272-
ContextBase::ContextBase(WasmBase *wasm, std::shared_ptr<PluginBase> plugin)
273-
: wasm_(wasm), id_(wasm->allocContextId()), parent_context_(this), root_id_(plugin->root_id_),
274-
root_log_prefix_(makeRootLogPrefix(plugin->vm_id_)), plugin_(plugin) {
275-
wasm_->contexts_[id_] = this;
272+
ContextBase::ContextBase(WasmBase *wasm, std::shared_ptr<PluginBase> plugin) {
273+
initializeRootBase(wasm, plugin);
276274
}
277275

278276
// NB: wasm can be nullptr if it failed to be created successfully.
@@ -290,6 +288,15 @@ WasmVm *ContextBase::wasmVm() const { return wasm_->wasm_vm(); }
290288

291289
bool ContextBase::isFailed() { return !wasm_ || wasm_->isFailed(); }
292290

291+
void ContextBase::initializeRootBase(WasmBase *wasm, std::shared_ptr<PluginBase> plugin) {
292+
wasm_ = wasm;
293+
id_ = wasm->allocContextId();
294+
root_id_ = plugin->root_id_;
295+
root_log_prefix_ = makeRootLogPrefix(plugin->vm_id_);
296+
parent_context_ = this;
297+
wasm_->contexts_[id_] = this;
298+
}
299+
293300
std::string ContextBase::makeRootLogPrefix(std::string_view vm_id) const {
294301
std::string prefix;
295302
if (!root_id_.empty()) {
@@ -308,10 +315,10 @@ bool ContextBase::onStart(std::shared_ptr<PluginBase> plugin) {
308315
DeferAfterCallActions actions(this);
309316
bool result = true;
310317
if (wasm_->on_context_create_) {
311-
temp_plugin_ = plugin;
318+
plugin_ = plugin;
312319
wasm_->on_context_create_(this, id_, 0);
313320
in_vm_context_created_ = true;
314-
temp_plugin_.reset();
321+
plugin_.reset();
315322
}
316323
if (wasm_->on_vm_start_) {
317324
// Do not set plugin_ as the on_vm_start handler should be independent of the plugin since the
@@ -343,11 +350,11 @@ bool ContextBase::onConfigure(std::shared_ptr<PluginBase> plugin) {
343350
}
344351

345352
DeferAfterCallActions actions(this);
346-
temp_plugin_ = plugin;
353+
plugin_ = plugin;
347354
auto result =
348355
wasm_->on_configure_(this, id_, static_cast<uint32_t>(plugin->plugin_configuration_.size()))
349356
.u64_ != 0;
350-
temp_plugin_.reset();
357+
plugin_.reset();
351358
return result;
352359
}
353360

@@ -637,8 +644,8 @@ WasmResult ContextBase::setTimerPeriod(std::chrono::milliseconds period,
637644
}
638645

639646
ContextBase::~ContextBase() {
640-
// Do not remove vm context which has the same lifetime as wasm_.
641-
if (id_) {
647+
// Do not remove vm or root contexts which have the same lifetime as wasm_.
648+
if (parent_context_id_) {
642649
wasm_->contexts_.erase(id_);
643650
}
644651
}

src/wasm.cc

Lines changed: 41 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -280,11 +280,7 @@ WasmBase::WasmBase(std::unique_ptr<WasmVm> wasm_vm, std::string_view vm_id,
280280
}
281281
}
282282

283-
WasmBase::~WasmBase() {
284-
root_contexts_.clear();
285-
pending_done_.clear();
286-
pending_delete_.clear();
287-
}
283+
WasmBase::~WasmBase() {}
288284

289285
bool WasmBase::initialize(const std::string &code, bool allow_precompiled) {
290286
if (!wasm_vm_) {
@@ -323,19 +319,22 @@ bool WasmBase::initialize(const std::string &code, bool allow_precompiled) {
323319
return !isFailed();
324320
}
325321

326-
ContextBase *WasmBase::getRootContext(const std::shared_ptr<PluginBase> &plugin,
327-
bool allow_closed) {
328-
auto it = root_contexts_.find(plugin->key());
329-
if (it != root_contexts_.end()) {
330-
return it->second.get();
322+
ContextBase *WasmBase::getRootContext(std::string_view root_id) {
323+
auto it = root_contexts_.find(std::string(root_id));
324+
if (it == root_contexts_.end()) {
325+
return nullptr;
331326
}
332-
if (allow_closed) {
333-
it = pending_done_.find(plugin->key());
334-
if (it != pending_done_.end()) {
335-
return it->second.get();
336-
}
327+
return it->second.get();
328+
}
329+
330+
ContextBase *WasmBase::getOrCreateRootContext(const std::shared_ptr<PluginBase> &plugin) {
331+
auto root_context = getRootContext(plugin->root_id_);
332+
if (!root_context) {
333+
auto context = std::unique_ptr<ContextBase>(createRootContext(plugin));
334+
root_context = context.get();
335+
root_contexts_[plugin->root_id_] = std::move(context);
337336
}
338-
return nullptr;
337+
return root_context;
339338
}
340339

341340
void WasmBase::startVm(ContextBase *root_context) {
@@ -353,14 +352,15 @@ bool WasmBase::configure(ContextBase *root_context, std::shared_ptr<PluginBase>
353352
}
354353

355354
ContextBase *WasmBase::start(std::shared_ptr<PluginBase> plugin) {
356-
auto it = root_contexts_.find(plugin->key());
355+
auto root_id = plugin->root_id_;
356+
auto it = root_contexts_.find(root_id);
357357
if (it != root_contexts_.end()) {
358358
it->second->onStart(plugin);
359359
return it->second.get();
360360
}
361361
auto context = std::unique_ptr<ContextBase>(createRootContext(plugin));
362362
auto context_ptr = context.get();
363-
root_contexts_[plugin->key()] = std::move(context);
363+
root_contexts_[root_id] = std::move(context);
364364
if (!context_ptr->onStart(plugin)) {
365365
return nullptr;
366366
}
@@ -377,49 +377,38 @@ uint32_t WasmBase::allocContextId() {
377377
}
378378
}
379379

380-
void WasmBase::startShutdown(const std::shared_ptr<PluginBase> &plugin) {
381-
auto it = root_contexts_.find(plugin->key());
382-
if (it != root_contexts_.end()) {
383-
if (it->second->onDone()) {
384-
it->second->onDelete();
385-
} else {
386-
pending_done_[it->first] = std::move(it->second);
387-
}
388-
root_contexts_.erase(it);
389-
}
390-
}
391-
392380
void WasmBase::startShutdown() {
393-
auto it = root_contexts_.begin();
394-
while (it != root_contexts_.end()) {
395-
if (it->second->onDone()) {
396-
it->second->onDelete();
397-
} else {
398-
pending_done_[it->first] = std::move(it->second);
381+
bool all_done = true;
382+
for (auto &p : root_contexts_) {
383+
if (!p.second->onDone()) {
384+
all_done = false;
385+
pending_done_.insert(p.second.get());
399386
}
400-
it = root_contexts_.erase(it);
387+
}
388+
if (!all_done) {
389+
shutdown_handle_ = std::make_unique<ShutdownHandle>(shared_from_this());
390+
} else {
391+
finishShutdown();
401392
}
402393
}
403394

404395
WasmResult WasmBase::done(ContextBase *root_context) {
405-
auto it = pending_done_.find(root_context->plugin_->key());
396+
auto it = pending_done_.find(root_context);
406397
if (it == pending_done_.end()) {
407398
return WasmResult::NotFound;
408399
}
409-
pending_delete_.insert(std::move(it->second));
410400
pending_done_.erase(it);
411-
// Defer the delete so that onDelete is not called from within the done() handler.
412-
shutdown_handle_ = std::make_unique<ShutdownHandle>(shared_from_this());
413-
addAfterVmCallAction(
414-
[shutdown_handle = shutdown_handle_.release()]() { delete shutdown_handle; });
401+
if (pending_done_.empty() && shutdown_handle_) {
402+
// Defer the delete so that onDelete is not called from within the done() handler.
403+
addAfterVmCallAction(
404+
[shutdown_handle = shutdown_handle_.release()]() { delete shutdown_handle; });
405+
}
415406
return WasmResult::Ok;
416407
}
417408

418409
void WasmBase::finishShutdown() {
419-
auto it = pending_delete_.begin();
420-
while (it != pending_delete_.end()) {
421-
(*it)->onDelete();
422-
it = pending_delete_.erase(it);
410+
for (auto &p : root_contexts_) {
411+
p.second->onDelete();
423412
}
424413
}
425414

@@ -531,18 +520,11 @@ getOrCreateThreadLocalWasm(std::shared_ptr<WasmHandleBase> base_wasm,
531520
WasmHandleCloneFactory clone_factory) {
532521
auto wasm_handle = getThreadLocalWasm(base_wasm->wasm()->vm_key());
533522
if (wasm_handle) {
534-
auto root_context = wasm_handle->wasm()->getRootContext(plugin, false);
535-
if (!root_context) {
536-
root_context = wasm_handle->wasm()->start(plugin);
537-
if (!root_context) {
538-
base_wasm->wasm()->fail(FailState::StartFailed, "Failed to start thread-local Wasm");
539-
return nullptr;
540-
}
541-
if (!wasm_handle->wasm()->configure(root_context, plugin)) {
542-
base_wasm->wasm()->fail(FailState::ConfigureFailed,
543-
"Failed to configure thread-local Wasm plugin");
544-
return nullptr;
545-
}
523+
auto root_context = wasm_handle->wasm()->getOrCreateRootContext(plugin);
524+
if (!wasm_handle->wasm()->configure(root_context, plugin)) {
525+
base_wasm->wasm()->fail(FailState::ConfigureFailed,
526+
"Failed to configure thread-local Wasm code");
527+
return nullptr;
546528
}
547529
return wasm_handle;
548530
}

0 commit comments

Comments
 (0)