[Lldb-commits] [lldb] [lldb] Refactoring JSONTransport into an abstract RPC Message Handler and transport layer. (PR #153121)
John Harrison via lldb-commits
lldb-commits at lists.llvm.org
Fri Aug 15 18:01:23 PDT 2025
================
@@ -54,112 +50,227 @@ class TransportUnhandledContentsError
std::string m_unhandled_contents;
};
-class TransportInvalidError : public llvm::ErrorInfo<TransportInvalidError> {
+/// A transport is responsible for maintaining the connection to a client
+/// application, and reading/writing structured messages to it.
+///
+/// Transports have limited thread safety requirements:
+/// - Messages will not be sent concurrently.
+/// - Messages MAY be sent while Run() is reading, or its callback is active.
+template <typename Req, typename Resp, typename Evt> class Transport {
public:
- static char ID;
-
- TransportInvalidError() = default;
+ using Message = std::variant<Req, Resp, Evt>;
+
+ virtual ~Transport() = default;
+
+ // Called by transport to send outgoing messages.
+ virtual void Event(const Evt &) = 0;
+ virtual void Request(const Req &) = 0;
+ virtual void Response(const Resp &) = 0;
+
+ /// Implemented to handle incoming messages. (See Run() below).
+ class MessageHandler {
+ public:
+ virtual ~MessageHandler() = default;
+ virtual void OnEvent(const Evt &) = 0;
+ virtual void OnRequest(const Req &) = 0;
+ virtual void OnResponse(const Resp &) = 0;
+ };
+
+ /// Called by server or client to receive messages from the connection.
+ /// The transport should in turn invoke the handler to process messages.
+ /// The MainLoop is used to handle reading from the incoming connection and
+ /// will run until the loop is terminated.
+ virtual llvm::Error Run(MainLoop &, MessageHandler &) = 0;
- void log(llvm::raw_ostream &OS) const override;
- std::error_code convertToErrorCode() const override;
+protected:
+ template <typename... Ts> inline auto Logv(const char *Fmt, Ts &&...Vals) {
+ Log(llvm::formatv(Fmt, std::forward<Ts>(Vals)...).str());
+ }
+ virtual void Log(llvm::StringRef message) = 0;
};
-/// A transport class that uses JSON for communication.
-class JSONTransport {
+/// A JSONTransport will encode and decode messages using JSON.
+template <typename Req, typename Resp, typename Evt>
+class JSONTransport : public Transport<Req, Resp, Evt> {
public:
- using ReadHandleUP = MainLoopBase::ReadHandleUP;
- template <typename T>
- using Callback = std::function<void(MainLoopBase &, const llvm::Expected<T>)>;
-
- JSONTransport(lldb::IOObjectSP input, lldb::IOObjectSP output);
- virtual ~JSONTransport() = default;
-
- /// Transport is not copyable.
- /// @{
- JSONTransport(const JSONTransport &rhs) = delete;
- void operator=(const JSONTransport &rhs) = delete;
- /// @}
-
- /// Writes a message to the output stream.
- template <typename T> llvm::Error Write(const T &t) {
- const std::string message = llvm::formatv("{0}", toJSON(t)).str();
- return WriteImpl(message);
+ using Transport<Req, Resp, Evt>::Transport;
+
+ JSONTransport(lldb::IOObjectSP in, lldb::IOObjectSP out)
+ : m_in(in), m_out(out) {}
+
+ void Event(const Evt &evt) override { Write(evt); }
+ void Request(const Req &req) override { Write(req); }
+ void Response(const Resp &resp) override { Write(resp); }
+
+ /// Run registers the transport with the given MainLoop and handles any
+ /// incoming messages using the given MessageHandler.
+ llvm::Error
+ Run(MainLoop &loop,
+ typename Transport<Req, Resp, Evt>::MessageHandler &handler) override {
+ llvm::Error error = llvm::Error::success();
+ Status status;
+ auto read_handle = loop.RegisterReadObject(
+ m_in,
+ std::bind(&JSONTransport::OnRead, this, &error, std::placeholders::_1,
+ std::ref(handler)),
+ status);
+ if (status.Fail()) {
+ // This error is only set if the read object handler is invoked, mark it
+ // as consumed if registration of the handler failed.
+ llvm::consumeError(std::move(error));
+ return status.takeError();
+ }
+
+ status = loop.Run();
----------------
ashgti wrote:
Updated to have a register function instead of a `Run` function.
https://github.com/llvm/llvm-project/pull/153121
More information about the lldb-commits
mailing list