starpc 0.44.0 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/echo/echo.pb.js +1 -1
- package/dist/mock/mock.pb.js +1 -1
- package/dist/rpcstream/rpcstream.pb.js +1 -1
- package/dist/srpc/rpcproto.pb.js +1 -1
- package/echo/Cargo.toml +0 -4
- package/echo/echo.pb.go +1 -1
- package/echo/echo.pb.rs +9 -0
- package/echo/echo.pb.ts +1 -1
- package/echo/echo_e2e_test.cpp +793 -34
- package/echo/echo_srpc.pb.cpp +1 -1
- package/echo/echo_srpc.pb.go +1 -1
- package/echo/echo_srpc.pb.hpp +3 -1
- package/echo/echo_srpc.pb.rs +312 -0
- package/echo/gen/mod.rs +15 -2
- package/echo/main.rs +9 -0
- package/go.mod +4 -3
- package/go.sum +8 -6
- package/mock/mock.pb.go +1 -1
- package/mock/mock.pb.rs +9 -0
- package/mock/mock.pb.ts +1 -1
- package/mock/mock_srpc.pb.cpp +1 -1
- package/mock/mock_srpc.pb.go +1 -1
- package/mock/mock_srpc.pb.hpp +3 -1
- package/mock/mock_srpc.pb.rs +103 -0
- package/package.json +5 -4
- package/srpc/Cargo.toml +1 -2
- package/srpc/client-rpc.cpp +20 -18
- package/srpc/client-rpc.hpp +14 -11
- package/srpc/client.cpp +11 -15
- package/srpc/client.hpp +17 -25
- package/srpc/common-rpc.cpp +12 -13
- package/srpc/common-rpc.hpp +13 -11
- package/srpc/errors.hpp +33 -20
- package/srpc/handler.hpp +3 -3
- package/srpc/invoker.hpp +26 -29
- package/srpc/lib.rs +1 -0
- package/srpc/message.hpp +4 -6
- package/srpc/msg-stream.hpp +13 -11
- package/srpc/mux.cpp +18 -17
- package/srpc/mux.hpp +15 -14
- package/srpc/packet.cpp +24 -26
- package/srpc/packet.hpp +14 -17
- package/srpc/proto.rs +5 -0
- package/srpc/rpcproto.pb.go +1 -1
- package/srpc/rpcproto.pb.rs +62 -0
- package/srpc/rpcproto.pb.ts +1 -1
- package/srpc/rpcstream/mod.rs +38 -0
- package/srpc/rpcstream/proto.rs +286 -0
- package/srpc/rpcstream/stream.rs +517 -0
- package/srpc/rpcstream/writer.rs +150 -0
- package/srpc/server-rpc.cpp +21 -21
- package/srpc/server-rpc.hpp +15 -13
- package/srpc/starpc.hpp +1 -1
- package/srpc/stream.hpp +18 -16
- package/srpc/writer.hpp +15 -12
- package/echo/build.rs +0 -15
- package/srpc/build.rs +0 -15
- package/srpc/proto/mod.rs +0 -10
package/srpc/client-rpc.cpp
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
namespace starpc {
|
|
8
8
|
|
|
9
|
-
ClientRPC::ClientRPC(const std::string&
|
|
9
|
+
ClientRPC::ClientRPC(const std::string &service, const std::string &method) {
|
|
10
10
|
Init();
|
|
11
11
|
service_ = service;
|
|
12
12
|
method_ = method;
|
|
@@ -14,7 +14,8 @@ ClientRPC::ClientRPC(const std::string& service, const std::string& method) {
|
|
|
14
14
|
|
|
15
15
|
ClientRPC::~ClientRPC() = default;
|
|
16
16
|
|
|
17
|
-
Error ClientRPC::Start(PacketWriter*
|
|
17
|
+
Error ClientRPC::Start(PacketWriter *writer, bool write_first_msg,
|
|
18
|
+
const std::string &first_msg) {
|
|
18
19
|
if (writer == nullptr) {
|
|
19
20
|
return Error::NilWriter;
|
|
20
21
|
}
|
|
@@ -36,7 +37,8 @@ Error ClientRPC::Start(PacketWriter* writer, bool write_first_msg, const std::st
|
|
|
36
37
|
first_msg_empty = first_msg.empty();
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
auto pkt =
|
|
40
|
+
auto pkt =
|
|
41
|
+
NewCallStartPacket(service_, method_, first_msg, first_msg_empty);
|
|
40
42
|
err = writer->WritePacket(*pkt);
|
|
41
43
|
if (err != Error::OK) {
|
|
42
44
|
Cancel();
|
|
@@ -48,7 +50,7 @@ Error ClientRPC::Start(PacketWriter* writer, bool write_first_msg, const std::st
|
|
|
48
50
|
return err;
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
Error ClientRPC::HandlePacketData(const std::string&
|
|
53
|
+
Error ClientRPC::HandlePacketData(const std::string &data) {
|
|
52
54
|
srpc::Packet pkt;
|
|
53
55
|
if (!pkt.ParseFromString(data)) {
|
|
54
56
|
return Error::InvalidMessage;
|
|
@@ -66,28 +68,28 @@ void ClientRPC::HandleStreamClose(Error close_err) {
|
|
|
66
68
|
cv_.notify_all();
|
|
67
69
|
}
|
|
68
70
|
|
|
69
|
-
Error ClientRPC::HandlePacket(const srpc::Packet&
|
|
71
|
+
Error ClientRPC::HandlePacket(const srpc::Packet &msg) {
|
|
70
72
|
Error err = ValidatePacket(msg);
|
|
71
73
|
if (err != Error::OK) {
|
|
72
74
|
return err;
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
switch (msg.body_case()) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
78
|
+
case srpc::Packet::kCallStart:
|
|
79
|
+
return HandleCallStart(msg.call_start());
|
|
80
|
+
case srpc::Packet::kCallData:
|
|
81
|
+
return HandleCallData(msg.call_data());
|
|
82
|
+
case srpc::Packet::kCallCancel:
|
|
83
|
+
if (msg.call_cancel()) {
|
|
84
|
+
return HandleCallCancel();
|
|
85
|
+
}
|
|
86
|
+
return Error::OK;
|
|
87
|
+
default:
|
|
88
|
+
return Error::OK;
|
|
87
89
|
}
|
|
88
90
|
}
|
|
89
91
|
|
|
90
|
-
Error ClientRPC::HandleCallStart(const srpc::CallStart&
|
|
92
|
+
Error ClientRPC::HandleCallStart(const srpc::CallStart &pkt) {
|
|
91
93
|
// server-to-client calls not supported
|
|
92
94
|
return Error::UnrecognizedPacket;
|
|
93
95
|
}
|
|
@@ -101,4 +103,4 @@ void ClientRPC::Close() {
|
|
|
101
103
|
}
|
|
102
104
|
}
|
|
103
105
|
|
|
104
|
-
}
|
|
106
|
+
} // namespace starpc
|
package/srpc/client-rpc.hpp
CHANGED
|
@@ -11,26 +11,27 @@
|
|
|
11
11
|
namespace srpc {
|
|
12
12
|
class Packet;
|
|
13
13
|
class CallStart;
|
|
14
|
-
}
|
|
14
|
+
} // namespace srpc
|
|
15
15
|
|
|
16
16
|
namespace starpc {
|
|
17
17
|
|
|
18
18
|
// ClientRPC represents the client side of an on-going RPC call message stream.
|
|
19
19
|
// Matches Go ClientRPC struct in client-rpc.go
|
|
20
20
|
class ClientRPC : public CommonRPC, public MsgStreamRw {
|
|
21
|
-
|
|
21
|
+
public:
|
|
22
22
|
// Constructor matching NewClientRPC in Go
|
|
23
|
-
ClientRPC(const std::string&
|
|
23
|
+
ClientRPC(const std::string &service, const std::string &method);
|
|
24
24
|
~ClientRPC() override;
|
|
25
25
|
|
|
26
26
|
// Start sets the writer and writes the CallStart message.
|
|
27
27
|
// Must only be called once!
|
|
28
28
|
// Matches Go Start method in client-rpc.go
|
|
29
|
-
Error Start(PacketWriter*
|
|
29
|
+
Error Start(PacketWriter *writer, bool write_first_msg,
|
|
30
|
+
const std::string &first_msg);
|
|
30
31
|
|
|
31
32
|
// HandlePacketData handles an incoming unparsed message packet.
|
|
32
33
|
// Matches Go HandlePacketData in client-rpc.go
|
|
33
|
-
Error HandlePacketData(const std::string&
|
|
34
|
+
Error HandlePacketData(const std::string &data);
|
|
34
35
|
|
|
35
36
|
// HandleStreamClose handles the stream closing optionally with an error.
|
|
36
37
|
// Matches Go HandleStreamClose (overrides CommonRPC)
|
|
@@ -38,19 +39,20 @@ class ClientRPC : public CommonRPC, public MsgStreamRw {
|
|
|
38
39
|
|
|
39
40
|
// HandlePacket handles an incoming parsed message packet.
|
|
40
41
|
// Matches Go HandlePacket in client-rpc.go
|
|
41
|
-
Error HandlePacket(const srpc::Packet&
|
|
42
|
+
Error HandlePacket(const srpc::Packet &pkt);
|
|
42
43
|
|
|
43
44
|
// HandleCallStart handles the call start packet.
|
|
44
45
|
// Matches Go HandleCallStart in client-rpc.go
|
|
45
|
-
Error HandleCallStart(const srpc::CallStart&
|
|
46
|
+
Error HandleCallStart(const srpc::CallStart &pkt);
|
|
46
47
|
|
|
47
48
|
// Close releases any resources held by the ClientRPC.
|
|
48
49
|
// Matches Go Close in client-rpc.go
|
|
49
50
|
void Close();
|
|
50
51
|
|
|
51
52
|
// MsgStreamRw interface implementation
|
|
52
|
-
Error ReadOne(std::string*
|
|
53
|
-
Error WriteCallData(const std::string&
|
|
53
|
+
Error ReadOne(std::string *out) override { return CommonRPC::ReadOne(out); }
|
|
54
|
+
Error WriteCallData(const std::string &data, bool data_is_zero, bool complete,
|
|
55
|
+
Error err) override {
|
|
54
56
|
return CommonRPC::WriteCallData(data, data_is_zero, complete, err);
|
|
55
57
|
}
|
|
56
58
|
Error WriteCallCancel() override { return CommonRPC::WriteCallCancel(); }
|
|
@@ -58,8 +60,9 @@ class ClientRPC : public CommonRPC, public MsgStreamRw {
|
|
|
58
60
|
|
|
59
61
|
// NewClientRPC constructs a new ClientRPC session.
|
|
60
62
|
// Matches Go NewClientRPC function in client-rpc.go
|
|
61
|
-
inline std::unique_ptr<ClientRPC> NewClientRPC(const std::string&
|
|
63
|
+
inline std::unique_ptr<ClientRPC> NewClientRPC(const std::string &service,
|
|
64
|
+
const std::string &method) {
|
|
62
65
|
return std::make_unique<ClientRPC>(service, method);
|
|
63
66
|
}
|
|
64
67
|
|
|
65
|
-
}
|
|
68
|
+
} // namespace starpc
|
package/srpc/client.cpp
CHANGED
|
@@ -4,11 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
namespace starpc {
|
|
6
6
|
|
|
7
|
-
Error ClientImpl::ExecCall(
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const Message& in,
|
|
11
|
-
Message* out) {
|
|
7
|
+
Error ClientImpl::ExecCall(const std::string &service,
|
|
8
|
+
const std::string &method, const Message &in,
|
|
9
|
+
Message *out) {
|
|
12
10
|
std::string first_msg;
|
|
13
11
|
if (!in.SerializeToString(&first_msg)) {
|
|
14
12
|
return Error::InvalidMessage;
|
|
@@ -18,7 +16,7 @@ Error ClientImpl::ExecCall(
|
|
|
18
16
|
|
|
19
17
|
// Open the stream with handlers
|
|
20
18
|
auto [writer, err] = open_stream_(
|
|
21
|
-
[&client_rpc](const std::string&
|
|
19
|
+
[&client_rpc](const std::string &data) -> Error {
|
|
22
20
|
return client_rpc->HandlePacketData(data);
|
|
23
21
|
},
|
|
24
22
|
[&client_rpc](Error close_err) {
|
|
@@ -51,10 +49,9 @@ Error ClientImpl::ExecCall(
|
|
|
51
49
|
return Error::OK;
|
|
52
50
|
}
|
|
53
51
|
|
|
54
|
-
std::pair<std::unique_ptr<Stream>, Error>
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const Message* first_msg) {
|
|
52
|
+
std::pair<std::unique_ptr<Stream>, Error>
|
|
53
|
+
ClientImpl::NewStream(const std::string &service, const std::string &method,
|
|
54
|
+
const Message *first_msg) {
|
|
58
55
|
std::string first_msg_data;
|
|
59
56
|
if (first_msg != nullptr) {
|
|
60
57
|
if (!first_msg->SerializeToString(&first_msg_data)) {
|
|
@@ -66,7 +63,7 @@ std::pair<std::unique_ptr<Stream>, Error> ClientImpl::NewStream(
|
|
|
66
63
|
|
|
67
64
|
// Open the stream with handlers
|
|
68
65
|
auto [writer, err] = open_stream_(
|
|
69
|
-
[client_rpc](const std::string&
|
|
66
|
+
[client_rpc](const std::string &data) -> Error {
|
|
70
67
|
return client_rpc->HandlePacketData(data);
|
|
71
68
|
},
|
|
72
69
|
[client_rpc](Error close_err) {
|
|
@@ -85,9 +82,8 @@ std::pair<std::unique_ptr<Stream>, Error> ClientImpl::NewStream(
|
|
|
85
82
|
// Create MsgStream with close callback
|
|
86
83
|
// Note: We need to capture writer to extend its lifetime
|
|
87
84
|
auto writer_ptr = writer.release();
|
|
88
|
-
auto stream =
|
|
89
|
-
client_rpc.get(),
|
|
90
|
-
[client_rpc, writer_ptr]() {
|
|
85
|
+
auto stream =
|
|
86
|
+
std::make_unique<MsgStream>(client_rpc.get(), [client_rpc, writer_ptr]() {
|
|
91
87
|
client_rpc->Cancel();
|
|
92
88
|
if (writer_ptr) {
|
|
93
89
|
writer_ptr->Close();
|
|
@@ -102,4 +98,4 @@ std::pair<std::unique_ptr<Stream>, Error> ClientImpl::NewStream(
|
|
|
102
98
|
return {std::move(stream), Error::OK};
|
|
103
99
|
}
|
|
104
100
|
|
|
105
|
-
}
|
|
101
|
+
} // namespace starpc
|
package/srpc/client.hpp
CHANGED
|
@@ -18,50 +18,42 @@ namespace starpc {
|
|
|
18
18
|
// OpenStreamFunc opens a stream with a remote.
|
|
19
19
|
// msgHandler must not be called concurrently.
|
|
20
20
|
// Matches Go OpenStreamFunc in client.go
|
|
21
|
-
using OpenStreamFunc =
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
using OpenStreamFunc =
|
|
22
|
+
std::function<std::pair<std::unique_ptr<PacketWriter>, Error>(
|
|
23
|
+
PacketDataHandler msg_handler, CloseHandler close_handler)>;
|
|
24
24
|
|
|
25
25
|
// Client implements a SRPC client which can initiate RPC streams.
|
|
26
26
|
// Matches Go Client interface in client.go
|
|
27
27
|
class Client {
|
|
28
|
-
|
|
28
|
+
public:
|
|
29
29
|
virtual ~Client() = default;
|
|
30
30
|
|
|
31
31
|
// ExecCall executes a request/reply RPC with the remote.
|
|
32
|
-
virtual Error ExecCall(
|
|
33
|
-
|
|
34
|
-
const std::string& method,
|
|
35
|
-
const Message& in,
|
|
36
|
-
Message* out) = 0;
|
|
32
|
+
virtual Error ExecCall(const std::string &service, const std::string &method,
|
|
33
|
+
const Message &in, Message *out) = 0;
|
|
37
34
|
|
|
38
35
|
// NewStream starts a streaming RPC with the remote & returns the stream.
|
|
39
36
|
// firstMsg is optional (can be nullptr).
|
|
40
|
-
virtual std::pair<std::unique_ptr<Stream>, Error>
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const Message* first_msg) = 0;
|
|
37
|
+
virtual std::pair<std::unique_ptr<Stream>, Error>
|
|
38
|
+
NewStream(const std::string &service, const std::string &method,
|
|
39
|
+
const Message *first_msg) = 0;
|
|
44
40
|
};
|
|
45
41
|
|
|
46
42
|
// ClientImpl is the default implementation of Client with a transport.
|
|
47
43
|
// Matches Go client struct in client.go
|
|
48
44
|
class ClientImpl : public Client {
|
|
49
|
-
|
|
45
|
+
public:
|
|
50
46
|
explicit ClientImpl(OpenStreamFunc open_stream)
|
|
51
47
|
: open_stream_(std::move(open_stream)) {}
|
|
52
48
|
|
|
53
|
-
Error ExecCall(
|
|
54
|
-
|
|
55
|
-
const std::string& method,
|
|
56
|
-
const Message& in,
|
|
57
|
-
Message* out) override;
|
|
49
|
+
Error ExecCall(const std::string &service, const std::string &method,
|
|
50
|
+
const Message &in, Message *out) override;
|
|
58
51
|
|
|
59
|
-
std::pair<std::unique_ptr<Stream>, Error>
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const Message* first_msg) override;
|
|
52
|
+
std::pair<std::unique_ptr<Stream>, Error>
|
|
53
|
+
NewStream(const std::string &service, const std::string &method,
|
|
54
|
+
const Message *first_msg) override;
|
|
63
55
|
|
|
64
|
-
|
|
56
|
+
private:
|
|
65
57
|
OpenStreamFunc open_stream_;
|
|
66
58
|
};
|
|
67
59
|
|
|
@@ -71,4 +63,4 @@ inline std::unique_ptr<Client> NewClient(OpenStreamFunc open_stream) {
|
|
|
71
63
|
return std::make_unique<ClientImpl>(std::move(open_stream));
|
|
72
64
|
}
|
|
73
65
|
|
|
74
|
-
}
|
|
66
|
+
} // namespace starpc
|
package/srpc/common-rpc.cpp
CHANGED
|
@@ -24,23 +24,20 @@ void CommonRPC::Cancel() {
|
|
|
24
24
|
cv_.notify_all();
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
bool CommonRPC::IsCanceled() const {
|
|
28
|
-
return canceled_.load();
|
|
29
|
-
}
|
|
27
|
+
bool CommonRPC::IsCanceled() const { return canceled_.load(); }
|
|
30
28
|
|
|
31
|
-
void CommonRPC::SetWriter(PacketWriter*
|
|
29
|
+
void CommonRPC::SetWriter(PacketWriter *writer) {
|
|
32
30
|
std::lock_guard<std::mutex> lock(mtx_);
|
|
33
31
|
writer_ = writer;
|
|
34
32
|
}
|
|
35
33
|
|
|
36
|
-
Error CommonRPC::ReadOne(std::string*
|
|
34
|
+
Error CommonRPC::ReadOne(std::string *out) {
|
|
37
35
|
bool ctx_done = false;
|
|
38
36
|
|
|
39
37
|
while (true) {
|
|
40
38
|
std::unique_lock<std::mutex> lock(mtx_);
|
|
41
39
|
|
|
42
40
|
if (ctx_done && !data_closed_) {
|
|
43
|
-
// context must have been canceled locally
|
|
44
41
|
CloseLocked();
|
|
45
42
|
return Error::Canceled;
|
|
46
43
|
}
|
|
@@ -58,7 +55,6 @@ Error CommonRPC::ReadOne(std::string* out) {
|
|
|
58
55
|
return Error::EOF_;
|
|
59
56
|
}
|
|
60
57
|
|
|
61
|
-
// Wait for more data or state change
|
|
62
58
|
cv_.wait(lock, [this, &ctx_done]() {
|
|
63
59
|
if (canceled_.load()) {
|
|
64
60
|
ctx_done = true;
|
|
@@ -73,7 +69,8 @@ Error CommonRPC::ReadOne(std::string* out) {
|
|
|
73
69
|
}
|
|
74
70
|
}
|
|
75
71
|
|
|
76
|
-
Error CommonRPC::WriteCallData(const std::string&
|
|
72
|
+
Error CommonRPC::WriteCallData(const std::string &data, bool data_is_zero,
|
|
73
|
+
bool complete, Error err) {
|
|
77
74
|
// Check if already completed
|
|
78
75
|
if (local_completed_.load()) {
|
|
79
76
|
// If we're just marking completion and already completed, allow it (no-op)
|
|
@@ -94,7 +91,8 @@ Error CommonRPC::WriteCallData(const std::string& data, bool data_is_zero, bool
|
|
|
94
91
|
return Error::NilWriter;
|
|
95
92
|
}
|
|
96
93
|
|
|
97
|
-
auto pkt =
|
|
94
|
+
auto pkt =
|
|
95
|
+
NewCallDataPacket(data, data.empty() && data_is_zero, complete, err);
|
|
98
96
|
return writer_->WritePacket(*pkt);
|
|
99
97
|
}
|
|
100
98
|
|
|
@@ -116,7 +114,7 @@ Error CommonRPC::HandleCallCancel() {
|
|
|
116
114
|
return Error::OK;
|
|
117
115
|
}
|
|
118
116
|
|
|
119
|
-
Error CommonRPC::HandleCallData(const srpc::CallData&
|
|
117
|
+
Error CommonRPC::HandleCallData(const srpc::CallData &pkt) {
|
|
120
118
|
std::lock_guard<std::mutex> lock(mtx_);
|
|
121
119
|
|
|
122
120
|
if (data_closed_) {
|
|
@@ -136,8 +134,9 @@ Error CommonRPC::HandleCallData(const srpc::CallData& pkt) {
|
|
|
136
134
|
bool complete = pkt.complete();
|
|
137
135
|
if (!pkt.error().empty()) {
|
|
138
136
|
complete = true;
|
|
139
|
-
// Store remote error - in a full implementation we might parse the error
|
|
140
|
-
|
|
137
|
+
// Store remote error - in a full implementation we might parse the error
|
|
138
|
+
// string
|
|
139
|
+
remote_err_ = Error::Unimplemented; // Generic remote error
|
|
141
140
|
}
|
|
142
141
|
|
|
143
142
|
if (complete) {
|
|
@@ -180,4 +179,4 @@ void CommonRPC::CloseLocked() {
|
|
|
180
179
|
canceled_.store(true);
|
|
181
180
|
}
|
|
182
181
|
|
|
183
|
-
}
|
|
182
|
+
} // namespace starpc
|
package/srpc/common-rpc.hpp
CHANGED
|
@@ -18,7 +18,7 @@ namespace starpc {
|
|
|
18
18
|
// CommonRPC contains common logic between server/client RPC.
|
|
19
19
|
// Matches Go commonRPC struct in common-rpc.go
|
|
20
20
|
class CommonRPC {
|
|
21
|
-
|
|
21
|
+
public:
|
|
22
22
|
CommonRPC();
|
|
23
23
|
virtual ~CommonRPC();
|
|
24
24
|
|
|
@@ -32,19 +32,20 @@ class CommonRPC {
|
|
|
32
32
|
bool IsCanceled() const;
|
|
33
33
|
|
|
34
34
|
// GetService returns the service name.
|
|
35
|
-
const std::string&
|
|
35
|
+
const std::string &GetService() const { return service_; }
|
|
36
36
|
|
|
37
37
|
// GetMethod returns the method name.
|
|
38
|
-
const std::string&
|
|
38
|
+
const std::string &GetMethod() const { return method_; }
|
|
39
39
|
|
|
40
40
|
// ReadOne reads a single message and returns.
|
|
41
41
|
// Returns EOF_ if the stream ended without a packet.
|
|
42
42
|
// Matches Go ReadOne in common-rpc.go
|
|
43
|
-
Error ReadOne(std::string*
|
|
43
|
+
Error ReadOne(std::string *out);
|
|
44
44
|
|
|
45
45
|
// WriteCallData writes a call data packet.
|
|
46
46
|
// Matches Go WriteCallData in common-rpc.go
|
|
47
|
-
Error WriteCallData(const std::string&
|
|
47
|
+
Error WriteCallData(const std::string &data, bool data_is_zero, bool complete,
|
|
48
|
+
Error err);
|
|
48
49
|
|
|
49
50
|
// HandleStreamClose handles the incoming stream closing with optional error.
|
|
50
51
|
// Matches Go HandleStreamClose in common-rpc.go
|
|
@@ -56,23 +57,24 @@ class CommonRPC {
|
|
|
56
57
|
|
|
57
58
|
// HandleCallData handles the call data packet.
|
|
58
59
|
// Matches Go HandleCallData in common-rpc.go
|
|
59
|
-
Error HandleCallData(const srpc::CallData&
|
|
60
|
+
Error HandleCallData(const srpc::CallData &pkt);
|
|
60
61
|
|
|
61
62
|
// WriteCallCancel writes a call cancel packet.
|
|
62
63
|
// Matches Go WriteCallCancel in common-rpc.go
|
|
63
64
|
Error WriteCallCancel();
|
|
64
65
|
|
|
65
|
-
// WriteCallCancelLocked is the same as WriteCallCancel but assumes mtx_ is
|
|
66
|
+
// WriteCallCancelLocked is the same as WriteCallCancel but assumes mtx_ is
|
|
67
|
+
// held.
|
|
66
68
|
Error WriteCallCancelLocked();
|
|
67
69
|
|
|
68
|
-
|
|
70
|
+
protected:
|
|
69
71
|
// CloseLocked releases resources held by the RPC.
|
|
70
72
|
// Must be called with mutex held.
|
|
71
73
|
// Matches Go closeLocked in common-rpc.go
|
|
72
74
|
void CloseLocked();
|
|
73
75
|
|
|
74
76
|
// SetWriter sets the packet writer.
|
|
75
|
-
void SetWriter(PacketWriter*
|
|
77
|
+
void SetWriter(PacketWriter *writer);
|
|
76
78
|
|
|
77
79
|
// Mutex and condition variable for synchronization (replaces Go broadcast)
|
|
78
80
|
mutable std::mutex mtx_;
|
|
@@ -87,7 +89,7 @@ class CommonRPC {
|
|
|
87
89
|
std::atomic<bool> local_completed_{false};
|
|
88
90
|
|
|
89
91
|
// Writer to write messages to
|
|
90
|
-
PacketWriter*
|
|
92
|
+
PacketWriter *writer_ = nullptr;
|
|
91
93
|
|
|
92
94
|
// dataQueue contains incoming data packets.
|
|
93
95
|
// Note: packets may be empty
|
|
@@ -104,4 +106,4 @@ class CommonRPC {
|
|
|
104
106
|
std::atomic<bool> canceled_{false};
|
|
105
107
|
};
|
|
106
108
|
|
|
107
|
-
}
|
|
109
|
+
} // namespace starpc
|
package/srpc/errors.hpp
CHANGED
|
@@ -8,8 +8,8 @@ namespace starpc {
|
|
|
8
8
|
// Error codes matching Go starpc errors (see errors.go)
|
|
9
9
|
enum class Error {
|
|
10
10
|
OK = 0,
|
|
11
|
-
Unimplemented,
|
|
12
|
-
Completed,
|
|
11
|
+
Unimplemented, // ErrUnimplemented - RPC method was not implemented
|
|
12
|
+
Completed, // ErrCompleted - unexpected packet after rpc was completed
|
|
13
13
|
UnrecognizedPacket, // ErrUnrecognizedPacket - unrecognized packet type
|
|
14
14
|
EmptyPacket, // ErrEmptyPacket - invalid empty packet
|
|
15
15
|
InvalidMessage, // ErrInvalidMessage - message failed to parse
|
|
@@ -22,37 +22,50 @@ enum class Error {
|
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
// Convert Error to string (matches Go error messages)
|
|
25
|
-
inline const char*
|
|
25
|
+
inline const char *ErrorString(Error err) {
|
|
26
26
|
switch (err) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
27
|
+
case Error::OK:
|
|
28
|
+
return "ok";
|
|
29
|
+
case Error::Unimplemented:
|
|
30
|
+
return "unimplemented";
|
|
31
|
+
case Error::Completed:
|
|
32
|
+
return "unexpected packet after rpc was completed";
|
|
33
|
+
case Error::UnrecognizedPacket:
|
|
34
|
+
return "unrecognized packet type";
|
|
35
|
+
case Error::EmptyPacket:
|
|
36
|
+
return "invalid empty packet";
|
|
37
|
+
case Error::InvalidMessage:
|
|
38
|
+
return "invalid message";
|
|
39
|
+
case Error::EmptyMethodID:
|
|
40
|
+
return "method id empty";
|
|
41
|
+
case Error::EmptyServiceID:
|
|
42
|
+
return "service id empty";
|
|
43
|
+
case Error::NoAvailableClients:
|
|
44
|
+
return "no available rpc clients";
|
|
45
|
+
case Error::NilWriter:
|
|
46
|
+
return "writer cannot be nil";
|
|
47
|
+
case Error::Canceled:
|
|
48
|
+
return "canceled";
|
|
49
|
+
case Error::EOF_:
|
|
50
|
+
return "EOF";
|
|
51
|
+
default:
|
|
52
|
+
return "unknown error";
|
|
40
53
|
}
|
|
41
54
|
}
|
|
42
55
|
|
|
43
56
|
// StarpcError exception for error propagation
|
|
44
57
|
class StarpcError : public std::runtime_error {
|
|
45
|
-
|
|
58
|
+
public:
|
|
46
59
|
explicit StarpcError(Error code)
|
|
47
60
|
: std::runtime_error(ErrorString(code)), code_(code) {}
|
|
48
61
|
|
|
49
|
-
StarpcError(Error code, const std::string&
|
|
62
|
+
StarpcError(Error code, const std::string &message)
|
|
50
63
|
: std::runtime_error(message), code_(code) {}
|
|
51
64
|
|
|
52
65
|
Error code() const noexcept { return code_; }
|
|
53
66
|
|
|
54
|
-
|
|
67
|
+
private:
|
|
55
68
|
Error code_;
|
|
56
69
|
};
|
|
57
70
|
|
|
58
|
-
}
|
|
71
|
+
} // namespace starpc
|
package/srpc/handler.hpp
CHANGED
|
@@ -10,14 +10,14 @@ namespace starpc {
|
|
|
10
10
|
// Handler describes a SRPC call handler implementation.
|
|
11
11
|
// Matches Go Handler interface in handler.go
|
|
12
12
|
class Handler : public Invoker {
|
|
13
|
-
|
|
13
|
+
public:
|
|
14
14
|
~Handler() override = default;
|
|
15
15
|
|
|
16
16
|
// GetServiceID returns the ID of the service.
|
|
17
|
-
virtual const std::string&
|
|
17
|
+
virtual const std::string &GetServiceID() const = 0;
|
|
18
18
|
|
|
19
19
|
// GetMethodIDs returns the list of methods for the service.
|
|
20
20
|
virtual std::vector<std::string> GetMethodIDs() const = 0;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
}
|
|
23
|
+
} // namespace starpc
|
package/srpc/invoker.hpp
CHANGED
|
@@ -12,47 +12,47 @@ namespace starpc {
|
|
|
12
12
|
// Invoker is a function for invoking SRPC service methods.
|
|
13
13
|
// Matches Go Invoker interface in invoker.go
|
|
14
14
|
class Invoker {
|
|
15
|
-
|
|
15
|
+
public:
|
|
16
16
|
virtual ~Invoker() = default;
|
|
17
17
|
|
|
18
18
|
// InvokeMethod invokes the method matching the service & method ID.
|
|
19
19
|
// Returns {found, error} - found is false if method not found.
|
|
20
20
|
// If service string is empty, ignore it.
|
|
21
|
-
virtual std::pair<bool, Error> InvokeMethod(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
Stream* strm) = 0;
|
|
21
|
+
virtual std::pair<bool, Error> InvokeMethod(const std::string &service_id,
|
|
22
|
+
const std::string &method_id,
|
|
23
|
+
Stream *strm) = 0;
|
|
25
24
|
};
|
|
26
25
|
|
|
27
26
|
// QueryableInvoker can be used to check if a service and method is implemented.
|
|
28
27
|
// Matches Go QueryableInvoker interface in invoker.go
|
|
29
28
|
class QueryableInvoker {
|
|
30
|
-
|
|
29
|
+
public:
|
|
31
30
|
virtual ~QueryableInvoker() = default;
|
|
32
31
|
|
|
33
32
|
// HasService checks if the service ID exists in the handlers.
|
|
34
|
-
virtual bool HasService(const std::string&
|
|
33
|
+
virtual bool HasService(const std::string &service_id) const = 0;
|
|
35
34
|
|
|
36
35
|
// HasServiceMethod checks if <service-id, method-id> exists in the handlers.
|
|
37
|
-
virtual bool HasServiceMethod(const std::string&
|
|
36
|
+
virtual bool HasServiceMethod(const std::string &service_id,
|
|
37
|
+
const std::string &method_id) const = 0;
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
// InvokerSlice is a list of invokers.
|
|
41
41
|
// Matches Go InvokerSlice in invoker.go
|
|
42
42
|
class InvokerSlice : public Invoker {
|
|
43
|
-
|
|
43
|
+
public:
|
|
44
44
|
InvokerSlice() = default;
|
|
45
|
-
explicit InvokerSlice(std::vector<Invoker*> invokers)
|
|
45
|
+
explicit InvokerSlice(std::vector<Invoker *> invokers)
|
|
46
46
|
: invokers_(std::move(invokers)) {}
|
|
47
47
|
|
|
48
|
-
void Add(Invoker*
|
|
48
|
+
void Add(Invoker *invoker) { invokers_.push_back(invoker); }
|
|
49
49
|
|
|
50
|
-
std::pair<bool, Error> InvokeMethod(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
std::pair<bool, Error> InvokeMethod(const std::string &service_id,
|
|
51
|
+
const std::string &method_id,
|
|
52
|
+
Stream *strm) override {
|
|
53
|
+
for (auto *invoker : invokers_) {
|
|
54
|
+
if (invoker == nullptr)
|
|
55
|
+
continue;
|
|
56
56
|
auto [found, err] = invoker->InvokeMethod(service_id, method_id, strm);
|
|
57
57
|
if (found || err != Error::OK) {
|
|
58
58
|
return {true, err};
|
|
@@ -61,34 +61,31 @@ class InvokerSlice : public Invoker {
|
|
|
61
61
|
return {false, Error::OK};
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
std::vector<Invoker*> invokers_;
|
|
64
|
+
private:
|
|
65
|
+
std::vector<Invoker *> invokers_;
|
|
66
66
|
};
|
|
67
67
|
|
|
68
68
|
// InvokerFunc is a function implementing InvokeMethod.
|
|
69
69
|
// Matches Go InvokerFunc in invoker.go
|
|
70
70
|
using InvokerFunc = std::function<std::pair<bool, Error>(
|
|
71
|
-
const std::string&
|
|
72
|
-
const std::string& method_id,
|
|
73
|
-
Stream* strm)>;
|
|
71
|
+
const std::string &service_id, const std::string &method_id, Stream *strm)>;
|
|
74
72
|
|
|
75
73
|
// InvokerFuncWrapper wraps an InvokerFunc as an Invoker.
|
|
76
74
|
class InvokerFuncWrapper : public Invoker {
|
|
77
|
-
|
|
75
|
+
public:
|
|
78
76
|
explicit InvokerFuncWrapper(InvokerFunc fn) : fn_(std::move(fn)) {}
|
|
79
77
|
|
|
80
|
-
std::pair<bool, Error> InvokeMethod(
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
Stream* strm) override {
|
|
78
|
+
std::pair<bool, Error> InvokeMethod(const std::string &service_id,
|
|
79
|
+
const std::string &method_id,
|
|
80
|
+
Stream *strm) override {
|
|
84
81
|
if (!fn_) {
|
|
85
82
|
return {false, Error::OK};
|
|
86
83
|
}
|
|
87
84
|
return fn_(service_id, method_id, strm);
|
|
88
85
|
}
|
|
89
86
|
|
|
90
|
-
|
|
87
|
+
private:
|
|
91
88
|
InvokerFunc fn_;
|
|
92
89
|
};
|
|
93
90
|
|
|
94
|
-
}
|
|
91
|
+
} // namespace starpc
|