starpc 0.52.1 → 0.52.2
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/README.md +37 -8
- package/dist/srpc/client-rpc.d.ts +1 -0
- package/dist/srpc/client-rpc.js +9 -0
- package/dist/srpc/client-rpc.test.d.ts +1 -0
- package/dist/srpc/client-rpc.test.js +50 -0
- package/dist/srpc/common-rpc.d.ts +5 -0
- package/dist/srpc/common-rpc.js +37 -8
- package/dist/srpc/errors.d.ts +2 -0
- package/dist/srpc/errors.js +14 -0
- package/dist/srpc/index.d.ts +1 -1
- package/dist/srpc/index.js +1 -1
- package/echo/Cargo.toml +8 -0
- package/echo/echo_e2e_test.cpp +542 -985
- package/echo/echo_srpc.pb.cpp +3 -5
- package/echo/echo_srpc.pb.go +6 -9
- package/echo/echo_srpc.pb.hpp +23 -3
- package/echo/echo_srpc.pb.rs +61 -26
- package/echo/echo_srpc.py +4 -1
- package/echo/half_close_test.rs +178 -0
- package/echo/integration_server.rs +14 -21
- package/echo/main.rs +28 -48
- package/go.mod +1 -1
- package/go.sum +2 -18
- package/integration/cross-language/cpp-client.cpp +446 -402
- package/integration/cross-language/cpp-pipe-server.cpp +139 -0
- package/integration/cross-language/cpp-pipe_test.go +114 -0
- package/integration/cross-language/cpp-server.cpp +222 -186
- package/mock/mock_srpc.pb.cpp +1 -1
- package/mock/mock_srpc.pb.hpp +1 -1
- package/mock/mock_srpc.pb.rs +10 -9
- package/package.json +1 -1
- package/srpc/CMakeLists.txt +3 -58
- package/srpc/README-cpp.md +69 -0
- package/srpc/accept.go +10 -4
- package/srpc/accept_test.go +25 -0
- package/srpc/build.rs +129 -34
- package/srpc/client-half-close_test.go +152 -0
- package/srpc/client-invoker.go +32 -42
- package/srpc/client-invoker_test.go +53 -0
- package/srpc/client-rpc.cpp +65 -80
- package/srpc/client-rpc.go +32 -33
- package/srpc/client-rpc.hpp +52 -38
- package/srpc/client-rpc.test.ts +67 -0
- package/srpc/client-rpc.ts +10 -0
- package/srpc/client-rpc_test.go +76 -0
- package/srpc/client.cpp +99 -87
- package/srpc/client.hpp +46 -35
- package/srpc/client.rs +78 -38
- package/srpc/client_half_close_test.cc +331 -0
- package/srpc/client_invoker.rs +75 -0
- package/srpc/common-rpc.cpp +186 -146
- package/srpc/common-rpc.go +5 -4
- package/srpc/common-rpc.hpp +119 -89
- package/srpc/common-rpc.ts +43 -8
- package/srpc/common-rpc_test.go +23 -0
- package/srpc/error.rs +19 -2
- package/srpc/errors.hpp +80 -50
- package/srpc/errors.ts +16 -0
- package/srpc/handler.hpp +9 -7
- package/srpc/handler.rs +7 -45
- package/srpc/index.ts +2 -0
- package/srpc/invoker.hpp +82 -55
- package/srpc/invoker.rs +14 -52
- package/srpc/lib.rs +2 -0
- package/srpc/message.hpp +17 -12
- package/srpc/msg-stream.go +1 -0
- package/srpc/msg-stream.hpp +108 -61
- package/srpc/mux.cpp +84 -84
- package/srpc/mux.hpp +48 -38
- package/srpc/mux.rs +4 -4
- package/srpc/net.go +12 -3
- package/srpc/packet.cpp +60 -58
- package/srpc/packet.hpp +35 -20
- package/srpc/packet.rs +8 -27
- package/srpc/rpc.rs +332 -115
- package/srpc/rpc_lifecycle_test.cc +333 -0
- package/srpc/server-cancel_test.go +39 -0
- package/srpc/server-rpc.cpp +83 -73
- package/srpc/server-rpc.go +21 -19
- package/srpc/server-rpc.hpp +56 -37
- package/srpc/server.rs +76 -131
- package/srpc/starpc.hpp +4 -2
- package/srpc/stream.go +4 -0
- package/srpc/stream.hpp +95 -34
- package/srpc/stream.rs +7 -2
- package/srpc/testing.rs +11 -66
- package/srpc/transport.rs +21 -71
- package/srpc/websocket.rs +106 -57
- package/srpc/writer.hpp +46 -32
- package/srpc/yamux.rs +82 -26
- package/srpc/tests/integration_test.rs +0 -495
package/srpc/common-rpc.cpp
CHANGED
|
@@ -6,177 +6,217 @@
|
|
|
6
6
|
#include "rpcproto.pb.h"
|
|
7
7
|
|
|
8
8
|
namespace starpc {
|
|
9
|
+
namespace {
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
/*
|
|
12
|
+
* These bounds contain an unconsumed stream, including zero-length messages.
|
|
13
|
+
*/
|
|
14
|
+
constexpr size_t maximum_queued_bytes = 4 * 1024 * 1024;
|
|
15
|
+
constexpr size_t maximum_queued_messages = 1024;
|
|
16
|
+
|
|
17
|
+
} // namespace
|
|
11
18
|
|
|
19
|
+
CommonRPC::CommonRPC() = default;
|
|
12
20
|
CommonRPC::~CommonRPC() = default;
|
|
13
21
|
|
|
14
|
-
void CommonRPC::
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
void CommonRPC::Cancel()
|
|
23
|
+
{
|
|
24
|
+
{
|
|
25
|
+
std::lock_guard lock(state_mutex);
|
|
26
|
+
canceled = true;
|
|
27
|
+
local_completed = true;
|
|
28
|
+
data_queue.clear();
|
|
29
|
+
queued_bytes = 0;
|
|
30
|
+
}
|
|
31
|
+
state_changed.notify_all();
|
|
32
|
+
stop_source.request_stop();
|
|
33
|
+
CloseWriter();
|
|
20
34
|
}
|
|
21
35
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
36
|
+
bool CommonRPC::IsCanceled() const
|
|
37
|
+
{
|
|
38
|
+
std::lock_guard lock(state_mutex);
|
|
39
|
+
return canceled;
|
|
25
40
|
}
|
|
26
41
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
writer_ = writer;
|
|
42
|
+
std::string CommonRPC::RemoteErrorMessage() const
|
|
43
|
+
{
|
|
44
|
+
std::lock_guard lock(state_mutex);
|
|
45
|
+
return remote_error_message;
|
|
32
46
|
}
|
|
33
47
|
|
|
34
|
-
Error CommonRPC::ReadOne(std::string *out)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
return Error::EOF_;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
cv_.wait(lock, [this, &ctx_done]() {
|
|
59
|
-
if (canceled_.load()) {
|
|
60
|
-
ctx_done = true;
|
|
61
|
-
return true;
|
|
62
|
-
}
|
|
63
|
-
return !data_queue_.empty() || data_closed_ || remote_err_ != Error::OK;
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
if (canceled_.load()) {
|
|
67
|
-
ctx_done = true;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
48
|
+
Error CommonRPC::ReadOne(std::string *out)
|
|
49
|
+
{
|
|
50
|
+
auto readable = [this] {
|
|
51
|
+
return canceled || data_closed || !data_queue.empty();
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/* Wait for a message, the call's end, or cancellation. */
|
|
55
|
+
std::unique_lock lock(state_mutex);
|
|
56
|
+
state_changed.wait(lock, readable);
|
|
57
|
+
|
|
58
|
+
if (canceled)
|
|
59
|
+
return remote_error != Error::OK ? remote_error
|
|
60
|
+
: Error::Canceled;
|
|
61
|
+
if (!data_queue.empty()) {
|
|
62
|
+
*out = std::move(data_queue.front());
|
|
63
|
+
queued_bytes -= out->size();
|
|
64
|
+
data_queue.pop_front();
|
|
65
|
+
return Error::OK;
|
|
66
|
+
}
|
|
67
|
+
return remote_error != Error::OK ? remote_error : Error::EOF_;
|
|
70
68
|
}
|
|
71
69
|
|
|
72
70
|
Error CommonRPC::WriteCallData(const std::string &data, bool data_is_zero,
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
71
|
+
bool complete, Error err)
|
|
72
|
+
{
|
|
73
|
+
std::unique_lock writing(write_mutex);
|
|
74
|
+
PacketWriter *w;
|
|
75
|
+
{
|
|
76
|
+
std::lock_guard lock(state_mutex);
|
|
77
|
+
if (canceled)
|
|
78
|
+
return Error::Canceled;
|
|
79
|
+
if (local_completed) {
|
|
80
|
+
return complete && data.empty() && !data_is_zero
|
|
81
|
+
? Error::OK
|
|
82
|
+
: Error::Completed;
|
|
83
|
+
}
|
|
84
|
+
if (writer == nullptr)
|
|
85
|
+
return Error::NilWriter;
|
|
86
|
+
if (writer_closed)
|
|
87
|
+
return Error::Completed;
|
|
88
|
+
if (complete || err != Error::OK)
|
|
89
|
+
local_completed = true;
|
|
90
|
+
w = writer;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const auto packet = NewCallDataPacket(
|
|
94
|
+
data, data.empty() && data_is_zero, complete, err);
|
|
95
|
+
const auto written = w->WritePacket(*packet);
|
|
96
|
+
writing.unlock();
|
|
97
|
+
|
|
98
|
+
/*
|
|
99
|
+
* A failed half-close leaves the verdict to the transport close, which
|
|
100
|
+
* follows any reply and completion the transport read but has not
|
|
101
|
+
* delivered.
|
|
102
|
+
*/
|
|
103
|
+
const bool half_close =
|
|
104
|
+
complete && data.empty() && !data_is_zero && err == Error::OK;
|
|
105
|
+
if (written != Error::OK && !half_close)
|
|
106
|
+
HandleStreamClose(written);
|
|
107
|
+
return written;
|
|
97
108
|
}
|
|
98
109
|
|
|
99
|
-
void CommonRPC::HandleStreamClose(Error close_err)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
+
void CommonRPC::HandleStreamClose(Error close_err)
|
|
111
|
+
{
|
|
112
|
+
{
|
|
113
|
+
std::lock_guard lock(state_mutex);
|
|
114
|
+
if (canceled)
|
|
115
|
+
return;
|
|
116
|
+
if (close_err == Error::EOF_)
|
|
117
|
+
close_err = Error::OK;
|
|
118
|
+
if (remote_error == Error::OK && close_err != Error::OK)
|
|
119
|
+
remote_error = close_err;
|
|
120
|
+
if (remote_error == Error::OK && !remote_completed &&
|
|
121
|
+
!local_completing)
|
|
122
|
+
remote_error = Error::ClosedBeforeCompletion;
|
|
123
|
+
data_closed = true;
|
|
124
|
+
}
|
|
125
|
+
state_changed.notify_all();
|
|
126
|
+
stop_source.request_stop();
|
|
127
|
+
CloseWriter();
|
|
110
128
|
}
|
|
111
129
|
|
|
112
|
-
Error CommonRPC::HandleCallCancel()
|
|
113
|
-
|
|
114
|
-
|
|
130
|
+
Error CommonRPC::HandleCallCancel()
|
|
131
|
+
{
|
|
132
|
+
Cancel();
|
|
133
|
+
return Error::OK;
|
|
115
134
|
}
|
|
116
135
|
|
|
117
|
-
Error CommonRPC::HandleCallData(const srpc::CallData &pkt)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
136
|
+
Error CommonRPC::HandleCallData(const srpc::CallData &pkt)
|
|
137
|
+
{
|
|
138
|
+
bool overflow = false;
|
|
139
|
+
{
|
|
140
|
+
std::lock_guard lock(state_mutex);
|
|
141
|
+
if (canceled)
|
|
142
|
+
return Error::Canceled;
|
|
143
|
+
if (data_closed)
|
|
144
|
+
return pkt.complete() ? Error::OK : Error::Completed;
|
|
145
|
+
if (!pkt.data().empty() || pkt.data_is_zero()) {
|
|
146
|
+
overflow =
|
|
147
|
+
data_queue.size() >= maximum_queued_messages ||
|
|
148
|
+
pkt.data().size() >
|
|
149
|
+
maximum_queued_bytes - queued_bytes;
|
|
150
|
+
if (!overflow) {
|
|
151
|
+
data_queue.push_back(pkt.data());
|
|
152
|
+
queued_bytes += pkt.data().size();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (!pkt.error().empty()) {
|
|
156
|
+
remote_error = Error::RemoteError;
|
|
157
|
+
remote_error_message = pkt.error();
|
|
158
|
+
}
|
|
159
|
+
if (pkt.complete() || remote_error != Error::OK) {
|
|
160
|
+
data_closed = true;
|
|
161
|
+
remote_completed = true;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* Close the transport before reporting an overflowing queue. */
|
|
166
|
+
if (overflow) {
|
|
167
|
+
HandleStreamClose(Error::ResourceExhausted);
|
|
168
|
+
return Error::ResourceExhausted;
|
|
169
|
+
}
|
|
170
|
+
state_changed.notify_all();
|
|
171
|
+
return Error::OK;
|
|
148
172
|
}
|
|
149
173
|
|
|
150
|
-
Error CommonRPC::WriteCallCancel()
|
|
151
|
-
|
|
152
|
-
|
|
174
|
+
Error CommonRPC::WriteCallCancel()
|
|
175
|
+
{
|
|
176
|
+
std::unique_lock writing(write_mutex);
|
|
177
|
+
PacketWriter *w;
|
|
178
|
+
{
|
|
179
|
+
std::lock_guard lock(state_mutex);
|
|
180
|
+
if (canceled || writer_closed)
|
|
181
|
+
return Error::Canceled;
|
|
182
|
+
if (local_completed)
|
|
183
|
+
return Error::Completed;
|
|
184
|
+
if (writer == nullptr)
|
|
185
|
+
return Error::NilWriter;
|
|
186
|
+
local_completed = true;
|
|
187
|
+
w = writer;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const auto written = w->WritePacket(*NewCallCancelPacket());
|
|
191
|
+
writing.unlock();
|
|
192
|
+
if (written != Error::OK)
|
|
193
|
+
HandleStreamClose(written);
|
|
194
|
+
return written;
|
|
153
195
|
}
|
|
154
196
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
return writer_->WritePacket(*pkt);
|
|
197
|
+
void CommonRPC::CloseWriter()
|
|
198
|
+
{
|
|
199
|
+
PacketWriter *w;
|
|
200
|
+
{
|
|
201
|
+
std::lock_guard lock(state_mutex);
|
|
202
|
+
if (writer_closed || writer == nullptr)
|
|
203
|
+
return;
|
|
204
|
+
writer_closed = true;
|
|
205
|
+
w = writer;
|
|
206
|
+
}
|
|
207
|
+
(void)w->Close();
|
|
167
208
|
}
|
|
168
209
|
|
|
169
|
-
void CommonRPC::
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
canceled_.store(true);
|
|
210
|
+
void CommonRPC::Finish(Error err)
|
|
211
|
+
{
|
|
212
|
+
{
|
|
213
|
+
std::lock_guard lock(state_mutex);
|
|
214
|
+
local_completing = true;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
(void)WriteCallData("", false, true, err);
|
|
218
|
+
CloseWriter();
|
|
219
|
+
stop_source.request_stop();
|
|
180
220
|
}
|
|
181
221
|
|
|
182
222
|
} // namespace starpc
|
package/srpc/common-rpc.go
CHANGED
|
@@ -288,13 +288,14 @@ func (c *commonRPC) WriteCallCancel() error {
|
|
|
288
288
|
return c.writer.WritePacket(NewCallCancelPacket())
|
|
289
289
|
}
|
|
290
290
|
|
|
291
|
-
// closeLocked releases resources held by the RPC.
|
|
291
|
+
// closeLocked releases resources held by the RPC. A call the remote already
|
|
292
|
+
// settled keeps its result: queued messages and the completion stay readable.
|
|
292
293
|
func (c *commonRPC) closeLocked(locked *broadcast.Locked) PacketWriter {
|
|
293
|
-
c.dataClosed
|
|
294
|
-
c.localCompleted.Store(true)
|
|
295
|
-
if c.remoteErr == nil {
|
|
294
|
+
if !c.dataClosed && c.remoteErr == nil {
|
|
296
295
|
c.remoteErr = context.Canceled
|
|
297
296
|
}
|
|
297
|
+
c.dataClosed = true
|
|
298
|
+
c.localCompleted.Store(true)
|
|
298
299
|
writer := c.closeWriterLocked()
|
|
299
300
|
locked.Broadcast()
|
|
300
301
|
c.cancelContext()
|
package/srpc/common-rpc.hpp
CHANGED
|
@@ -1,109 +1,139 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
-
#include
|
|
3
|
+
#include "errors.hpp"
|
|
4
|
+
#include "writer.hpp"
|
|
5
|
+
|
|
4
6
|
#include <condition_variable>
|
|
5
7
|
#include <deque>
|
|
6
8
|
#include <mutex>
|
|
9
|
+
#include <stop_token>
|
|
7
10
|
#include <string>
|
|
8
11
|
|
|
9
|
-
#include "errors.hpp"
|
|
10
|
-
#include "writer.hpp"
|
|
11
|
-
|
|
12
12
|
namespace srpc {
|
|
13
13
|
class CallData;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
namespace starpc {
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
/*
|
|
19
|
+
* CommonRPC holds the state one call shares between its transport side and
|
|
20
|
+
* its handler side: message delivery, half-close, and cancellation. The
|
|
21
|
+
* packet writer must outlive the call and interrupt blocked writes when
|
|
22
|
+
* closed. Subclasses drive it through Handle* from the transport and
|
|
23
|
+
* ReadOne/WriteCallData from the handler.
|
|
24
|
+
*/
|
|
20
25
|
class CommonRPC {
|
|
21
26
|
public:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
27
|
+
CommonRPC();
|
|
28
|
+
virtual ~CommonRPC();
|
|
29
|
+
|
|
30
|
+
/* Cancel interrupts reads and writes. Repeating it is safe. */
|
|
31
|
+
void Cancel();
|
|
32
|
+
|
|
33
|
+
/* IsCanceled reports whether Cancel or a peer cancel has run. */
|
|
34
|
+
bool IsCanceled() const;
|
|
35
|
+
|
|
36
|
+
/*
|
|
37
|
+
* StopToken lets handlers cancel work outside ReadOne when the call
|
|
38
|
+
* ends.
|
|
39
|
+
*/
|
|
40
|
+
std::stop_token StopToken() const
|
|
41
|
+
{
|
|
42
|
+
return stop_source.get_token();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* GetService and GetMethod stay stable after call startup. */
|
|
46
|
+
const std::string &GetService() const
|
|
47
|
+
{
|
|
48
|
+
return service;
|
|
49
|
+
}
|
|
50
|
+
const std::string &GetMethod() const
|
|
51
|
+
{
|
|
52
|
+
return method;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/*
|
|
56
|
+
* RemoteErrorMessage retains the peer's diagnostic when ReadOne
|
|
57
|
+
* returns RemoteError.
|
|
58
|
+
*/
|
|
59
|
+
std::string RemoteErrorMessage() const;
|
|
60
|
+
|
|
61
|
+
/*
|
|
62
|
+
* ReadOne returns the next queued message in out. It returns EOF_
|
|
63
|
+
* after a normal completion, the peer's error for a failed call, and
|
|
64
|
+
* Canceled after local cancellation; an abrupt peer disconnect is not
|
|
65
|
+
* a successful EOF.
|
|
66
|
+
*/
|
|
67
|
+
Error ReadOne(std::string *out);
|
|
68
|
+
|
|
69
|
+
/*
|
|
70
|
+
* WriteCallData writes one data packet. data_is_zero marks an
|
|
71
|
+
* intentionally empty message; complete ends the sending side; err
|
|
72
|
+
* carries the terminal verdict. A failed write ends the call, except
|
|
73
|
+
* for a bare half-close, whose outcome the transport close settles.
|
|
74
|
+
*/
|
|
75
|
+
Error WriteCallData(const std::string &data, bool data_is_zero,
|
|
76
|
+
bool complete, Error err);
|
|
77
|
+
|
|
78
|
+
/*
|
|
79
|
+
* HandleStreamClose records the transport ending. EOF_ means the peer
|
|
80
|
+
* half-closed cleanly; any other error becomes the call's verdict when
|
|
81
|
+
* the peer has not given one.
|
|
82
|
+
*/
|
|
83
|
+
void HandleStreamClose(Error close_err);
|
|
84
|
+
|
|
85
|
+
/* HandleCallCancel honors the peer's cancel packet. */
|
|
86
|
+
Error HandleCallCancel();
|
|
87
|
+
|
|
88
|
+
/* HandleCallData queues one data packet and applies its verdict. */
|
|
89
|
+
Error HandleCallData(const srpc::CallData &pkt);
|
|
90
|
+
|
|
91
|
+
/* WriteCallCancel writes cancel to the remote and ends the call. */
|
|
92
|
+
Error WriteCallCancel();
|
|
69
93
|
|
|
70
94
|
protected:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
95
|
+
/* Finish publishes err as the call's verdict and closes the writer. */
|
|
96
|
+
void Finish(Error err);
|
|
97
|
+
|
|
98
|
+
/* CloseWriter closes the transport once per call, outside the locks. */
|
|
99
|
+
void CloseWriter();
|
|
100
|
+
|
|
101
|
+
/*
|
|
102
|
+
* state_mutex guards the call state below. write_mutex orders outgoing
|
|
103
|
+
* packets and may precede state_mutex; transport close never waits for
|
|
104
|
+
* write_mutex.
|
|
105
|
+
*/
|
|
106
|
+
mutable std::mutex state_mutex;
|
|
107
|
+
std::mutex write_mutex;
|
|
108
|
+
std::condition_variable state_changed;
|
|
109
|
+
|
|
110
|
+
std::string service;
|
|
111
|
+
std::string method;
|
|
112
|
+
|
|
113
|
+
/* writer is borrowed until the call and transport callbacks stop. */
|
|
114
|
+
PacketWriter *writer = nullptr;
|
|
115
|
+
bool writer_closed = false;
|
|
116
|
+
|
|
117
|
+
/* local_completed is set once the handler side has sent its verdict. */
|
|
118
|
+
bool local_completed = false;
|
|
119
|
+
bool local_completing = false;
|
|
120
|
+
bool canceled = false;
|
|
121
|
+
|
|
122
|
+
/* data_closed ends the receive side; remote_completed records why. */
|
|
123
|
+
bool data_closed = false;
|
|
124
|
+
bool remote_completed = false;
|
|
125
|
+
Error remote_error = Error::OK;
|
|
126
|
+
std::string remote_error_message;
|
|
127
|
+
|
|
128
|
+
/*
|
|
129
|
+
* data_queue holds messages received before their reader ran, bounded
|
|
130
|
+
* by queued_bytes and the queue length.
|
|
131
|
+
*/
|
|
132
|
+
std::deque<std::string> data_queue;
|
|
133
|
+
size_t queued_bytes = 0;
|
|
134
|
+
|
|
135
|
+
/* stop_source drives StopToken; cancellation and close request it. */
|
|
136
|
+
std::stop_source stop_source;
|
|
107
137
|
};
|
|
108
138
|
|
|
109
139
|
} // namespace starpc
|