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.
52 lines
1.2 KiB
C++
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
|