Files
scylladb/lang/wasm_alien_thread_runner.hh
Wojciech Mitros 2fd6d495fa wasm: move compilation to an alien thread
The compilation of wasm UDFs is performed by a call to a foreign
function, which cannot be divided with yielding points and, as a
result, causes long reactor stalls for big UDFs.
We avoid them by submitting the compilation task to a non-seastar
std::thread, and retrieving the result using seastar::alien.

The thread is created at the start of the program. It executes
tasks from a queue in an infinite loop.

All seastar shards reference the thread through a std::shared_ptr
to a `alien_thread_runner`.

Considering that the compilation takes a long time anyway, the
alien_thread_runner is implemented with focus on simplicity more
than on performance. The tasks are stored in an std::queue, reading
and writing to it is synchronized using an std::mutex for reading/
writing to the queue, and an std::condition_variable waiting until
the queue has elements.

When the destructor of the alien runner is called, an std::nullopt
sentinel is pushed to the queue, and after all remaining tasks are
finished and the sentinel is read, the thread finishes.
2023-03-09 11:54:38 +01:00

52 lines
1.2 KiB
C++

/*
* Copyright (C) 2023-present ScyllaDB
*/
/*
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#pragma once
#include <functional>
#include <mutex>
#include <queue>
#include <condition_variable>
#include <thread>
#include <seastar/core/future.hh>
#include <seastar/util/noncopyable_function.hh>
#include "rust/cxx.h"
#include "rust/wasmtime_bindings.hh"
namespace wasm {
struct wasm_compile_task {
seastar::noncopyable_function<void()> func;
seastar::promise<rust::Box<wasmtime::Module>>& done;
unsigned shard;
};
struct task_queue {
std::mutex _mut;
std::condition_variable _cv;
std::queue<std::optional<wasm_compile_task>> _pending;
public:
std::optional<wasm_compile_task> pop_front();
void push_back(std::optional<wasm_compile_task> work_item);
};
class alien_thread_runner {
task_queue _pending_queue;
std::thread _thread;
public:
alien_thread_runner();
~alien_thread_runner();
alien_thread_runner(const alien_thread_runner&) = delete;
alien_thread_runner& operator=(const alien_thread_runner&) = delete;
void submit(seastar::promise<rust::Box<wasmtime::Module>>& p, std::function<rust::Box<wasmtime::Module>()> f);
};
} // namespace wasm