virtual void call()

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();
        }
      });
    }