in src/rpc.h [180:250]
virtual void call(BufferHandle inbuffer, Function<void(BufferHandle)> callback) noexcept override {
scheduler.run([rpc = makeMe(&rpc), this, inbuffer = std::move(inbuffer),
callback = std::move(callback)]() mutable noexcept {
try {
std::tuple<std::decay_t<Args>...> args;
constexpr bool isDeferred = std::is_invocable_r_v<void, F, RpcDeferredReturn<R>, Args...>;
auto in = [&]() {
uint32_t rid, fid;
std::apply(
[&](std::decay_t<Args>&... args) { deserializeBuffer(std::move(inbuffer), rid, fid, args...); }, args);
};
BufferHandle outbuffer;
auto out = [this, &args, &outbuffer]() {
if constexpr (!isDeferred) {
if constexpr (std::is_same_v<void, R>) {
std::apply(f, std::move(args));
serializeToBuffer(outbuffer, (uint32_t)0, (uint32_t)reqSuccess);
} else {
serializeToBuffer(outbuffer, (uint32_t)0, (uint32_t)reqSuccess, std::apply(f, std::move(args)));
}
}
};
auto exceptionMode = rpc->currentExceptionMode_.load(std::memory_order_relaxed);
if (exceptionMode == ExceptionMode::None) {
in();
out();
} else if (exceptionMode == ExceptionMode::DeserializationOnly) {
try {
in();
} catch (const std::exception& e) {
serializeToBuffer(outbuffer, (uint32_t)0, (uint32_t)reqError, std::string_view(e.what()));
std::move(callback)(std::move(outbuffer));
return;
}
out();
} else {
try {
in();
out();
} catch (const std::exception& e) {
serializeToBuffer(outbuffer, (uint32_t)0, (uint32_t)reqError, std::string_view(e.what()));
std::move(callback)(std::move(outbuffer));
return;
}
}
if constexpr (isDeferred) {
RpcDeferredReturn<R> d;
if constexpr (std::is_same_v<void, R>) {
d.f = [callback = std::move(callback)]() mutable noexcept {
BufferHandle outbuffer;
serializeToBuffer(outbuffer, (uint32_t)0, (uint32_t)reqSuccess);
std::move(callback)(std::move(outbuffer));
};
} else {
d.f = [callback = std::move(callback)](const R& r) mutable noexcept {
BufferHandle outbuffer;
serializeToBuffer(outbuffer, (uint32_t)0, (uint32_t)reqSuccess, r);
std::move(callback)(std::move(outbuffer));
};
}
auto wrap = [&](auto&&... args) { f(std::move(d), std::forward<decltype(args)>(args)...); };
std::apply(wrap, std::move(args));
} else {
std::move(callback)(std::move(outbuffer));
}
} catch (const std::exception& e) {
fprintf(stderr, "Unhandled exception in RPC function: %s\n", e.what());
std::abort();
}
});
}