|
|
@ -125,13 +125,14 @@ auto ChaoticGoodServerTransport::MaybePushFragmentIntoCall( |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
auto ChaoticGoodServerTransport::SendFragment( |
|
|
|
auto ChaoticGoodServerTransport::SendFragment( |
|
|
|
ServerFragmentFrame frame, MpscSender<ServerFrame> outgoing_frames) { |
|
|
|
ServerFragmentFrame frame, MpscSender<ServerFrame> outgoing_frames, |
|
|
|
|
|
|
|
CallInitiator call_initiator) { |
|
|
|
GRPC_TRACE_LOG(chaotic_good, INFO) |
|
|
|
GRPC_TRACE_LOG(chaotic_good, INFO) |
|
|
|
<< "CHAOTIC_GOOD: SendFragment: frame=" << frame.ToString(); |
|
|
|
<< "CHAOTIC_GOOD: SendFragment: frame=" << frame.ToString(); |
|
|
|
// Capture the call_initiator to ensure the underlying call spine is alive
|
|
|
|
// Capture the call_initiator to ensure the underlying call spine is alive
|
|
|
|
// until the outgoing_frames.Send promise completes.
|
|
|
|
// until the outgoing_frames.Send promise completes.
|
|
|
|
return Map(outgoing_frames.Send(std::move(frame)), |
|
|
|
return Map(outgoing_frames.Send(std::move(frame)), |
|
|
|
[](bool success) -> absl::Status { |
|
|
|
[call_initiator](bool success) -> absl::Status { |
|
|
|
if (!success) { |
|
|
|
if (!success) { |
|
|
|
// Failed to send outgoing frame.
|
|
|
|
// Failed to send outgoing frame.
|
|
|
|
return absl::UnavailableError("Transport closed."); |
|
|
|
return absl::UnavailableError("Transport closed."); |
|
|
@ -145,26 +146,27 @@ auto ChaoticGoodServerTransport::SendCallBody( |
|
|
|
CallInitiator call_initiator) { |
|
|
|
CallInitiator call_initiator) { |
|
|
|
// Continuously send client frame with client to server
|
|
|
|
// Continuously send client frame with client to server
|
|
|
|
// messages.
|
|
|
|
// messages.
|
|
|
|
return ForEach(OutgoingMessages(call_initiator), |
|
|
|
return ForEach( |
|
|
|
// Capture the call_initator to ensure the underlying call
|
|
|
|
OutgoingMessages(call_initiator), |
|
|
|
// spine is alive until the SendFragment promise completes.
|
|
|
|
// Capture the call_initator to ensure the underlying call
|
|
|
|
[stream_id, outgoing_frames, aligned_bytes = aligned_bytes_]( |
|
|
|
// spine is alive until the SendFragment promise completes.
|
|
|
|
MessageHandle message) mutable { |
|
|
|
[stream_id, outgoing_frames, call_initiator, |
|
|
|
ServerFragmentFrame frame; |
|
|
|
aligned_bytes = aligned_bytes_](MessageHandle message) mutable { |
|
|
|
// Construct frame header (flags, header_length
|
|
|
|
ServerFragmentFrame frame; |
|
|
|
// and trailer_length will be added in
|
|
|
|
// Construct frame header (flags, header_length
|
|
|
|
// serialization).
|
|
|
|
// and trailer_length will be added in
|
|
|
|
const uint32_t message_length = message->payload()->Length(); |
|
|
|
// serialization).
|
|
|
|
const uint32_t padding = |
|
|
|
const uint32_t message_length = message->payload()->Length(); |
|
|
|
message_length % aligned_bytes == 0 |
|
|
|
const uint32_t padding = |
|
|
|
? 0 |
|
|
|
message_length % aligned_bytes == 0 |
|
|
|
: aligned_bytes - (message_length % aligned_bytes); |
|
|
|
? 0 |
|
|
|
CHECK_EQ((message_length + padding) % aligned_bytes, 0u); |
|
|
|
: aligned_bytes - message_length % aligned_bytes; |
|
|
|
frame.message = FragmentMessage(std::move(message), padding, |
|
|
|
CHECK_EQ((message_length + padding) % aligned_bytes, 0u); |
|
|
|
message_length); |
|
|
|
frame.message = |
|
|
|
frame.stream_id = stream_id; |
|
|
|
FragmentMessage(std::move(message), padding, message_length); |
|
|
|
return SendFragment(std::move(frame), outgoing_frames); |
|
|
|
frame.stream_id = stream_id; |
|
|
|
}); |
|
|
|
return SendFragment(std::move(frame), outgoing_frames, call_initiator); |
|
|
|
|
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
auto ChaoticGoodServerTransport::SendCallInitialMetadataAndBody( |
|
|
|
auto ChaoticGoodServerTransport::SendCallInitialMetadataAndBody( |
|
|
@ -185,7 +187,8 @@ auto ChaoticGoodServerTransport::SendCallInitialMetadataAndBody( |
|
|
|
frame.headers = std::move(*md); |
|
|
|
frame.headers = std::move(*md); |
|
|
|
frame.stream_id = stream_id; |
|
|
|
frame.stream_id = stream_id; |
|
|
|
return TrySeq( |
|
|
|
return TrySeq( |
|
|
|
SendFragment(std::move(frame), outgoing_frames), |
|
|
|
SendFragment(std::move(frame), outgoing_frames, |
|
|
|
|
|
|
|
call_initiator), |
|
|
|
SendCallBody(stream_id, outgoing_frames, call_initiator)); |
|
|
|
SendCallBody(stream_id, outgoing_frames, call_initiator)); |
|
|
|
}, |
|
|
|
}, |
|
|
|
[]() { return absl::OkStatus(); }); |
|
|
|
[]() { return absl::OkStatus(); }); |
|
|
@ -206,11 +209,15 @@ auto ChaoticGoodServerTransport::CallOutboundLoop( |
|
|
|
return Empty{}; |
|
|
|
return Empty{}; |
|
|
|
}), |
|
|
|
}), |
|
|
|
call_initiator.PullServerTrailingMetadata(), |
|
|
|
call_initiator.PullServerTrailingMetadata(), |
|
|
|
[stream_id, outgoing_frames](ServerMetadataHandle md) mutable { |
|
|
|
// Capture the call_initator to ensure the underlying call_spine
|
|
|
|
|
|
|
|
// is alive until the SendFragment promise completes.
|
|
|
|
|
|
|
|
[stream_id, outgoing_frames, |
|
|
|
|
|
|
|
call_initiator](ServerMetadataHandle md) mutable { |
|
|
|
ServerFragmentFrame frame; |
|
|
|
ServerFragmentFrame frame; |
|
|
|
frame.trailers = std::move(md); |
|
|
|
frame.trailers = std::move(md); |
|
|
|
frame.stream_id = stream_id; |
|
|
|
frame.stream_id = stream_id; |
|
|
|
return SendFragment(std::move(frame), outgoing_frames); |
|
|
|
return SendFragment(std::move(frame), outgoing_frames, |
|
|
|
|
|
|
|
call_initiator); |
|
|
|
})); |
|
|
|
})); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -302,11 +309,10 @@ auto ChaoticGoodServerTransport::ReadOneFrame(ChaoticGoodTransport& transport) { |
|
|
|
call_initiator.has_value(), |
|
|
|
call_initiator.has_value(), |
|
|
|
[&call_initiator]() { |
|
|
|
[&call_initiator]() { |
|
|
|
auto c = std::move(*call_initiator); |
|
|
|
auto c = std::move(*call_initiator); |
|
|
|
return c.SpawnWaitable("cancel_from_read", |
|
|
|
return c.SpawnWaitable("cancel", [c]() mutable { |
|
|
|
[c]() mutable { |
|
|
|
c.Cancel(); |
|
|
|
c.Cancel(); |
|
|
|
return absl::OkStatus(); |
|
|
|
return absl::OkStatus(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
}, |
|
|
|
}, |
|
|
|
[]() -> absl::Status { return absl::OkStatus(); }); |
|
|
|
[]() -> absl::Status { return absl::OkStatus(); }); |
|
|
|
}), |
|
|
|
}), |
|
|
@ -391,8 +397,6 @@ void ChaoticGoodServerTransport::AbortWithError() { |
|
|
|
// Close all the available pipes.
|
|
|
|
// Close all the available pipes.
|
|
|
|
outgoing_frames_.MarkClosed(); |
|
|
|
outgoing_frames_.MarkClosed(); |
|
|
|
ReleasableMutexLock lock(&mu_); |
|
|
|
ReleasableMutexLock lock(&mu_); |
|
|
|
if (aborted_with_error_) return; |
|
|
|
|
|
|
|
aborted_with_error_ = true; |
|
|
|
|
|
|
|
StreamMap stream_map = std::move(stream_map_); |
|
|
|
StreamMap stream_map = std::move(stream_map_); |
|
|
|
stream_map_.clear(); |
|
|
|
stream_map_.clear(); |
|
|
|
state_tracker_.SetState(GRPC_CHANNEL_SHUTDOWN, |
|
|
|
state_tracker_.SetState(GRPC_CHANNEL_SHUTDOWN, |
|
|
@ -401,19 +405,18 @@ void ChaoticGoodServerTransport::AbortWithError() { |
|
|
|
lock.Release(); |
|
|
|
lock.Release(); |
|
|
|
for (const auto& pair : stream_map) { |
|
|
|
for (const auto& pair : stream_map) { |
|
|
|
auto call_initiator = pair.second; |
|
|
|
auto call_initiator = pair.second; |
|
|
|
call_initiator.SpawnInfallible("cancel_from_transport_closed", |
|
|
|
call_initiator.SpawnInfallible("cancel", [call_initiator]() mutable { |
|
|
|
[call_initiator]() mutable { |
|
|
|
call_initiator.Cancel(); |
|
|
|
call_initiator.Cancel(); |
|
|
|
return Empty{}; |
|
|
|
return Empty{}; |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
absl::optional<CallInitiator> ChaoticGoodServerTransport::LookupStream( |
|
|
|
absl::optional<CallInitiator> ChaoticGoodServerTransport::LookupStream( |
|
|
|
uint32_t stream_id) { |
|
|
|
uint32_t stream_id) { |
|
|
|
MutexLock lock(&mu_); |
|
|
|
|
|
|
|
GRPC_TRACE_LOG(chaotic_good, INFO) |
|
|
|
GRPC_TRACE_LOG(chaotic_good, INFO) |
|
|
|
<< "CHAOTIC_GOOD " << this << " LookupStream " << stream_id; |
|
|
|
<< "CHAOTIC_GOOD " << this << " LookupStream " << stream_id; |
|
|
|
|
|
|
|
MutexLock lock(&mu_); |
|
|
|
auto it = stream_map_.find(stream_id); |
|
|
|
auto it = stream_map_.find(stream_id); |
|
|
|
if (it == stream_map_.end()) return absl::nullopt; |
|
|
|
if (it == stream_map_.end()) return absl::nullopt; |
|
|
|
return it->second; |
|
|
|
return it->second; |
|
|
@ -421,9 +424,9 @@ absl::optional<CallInitiator> ChaoticGoodServerTransport::LookupStream( |
|
|
|
|
|
|
|
|
|
|
|
absl::optional<CallInitiator> ChaoticGoodServerTransport::ExtractStream( |
|
|
|
absl::optional<CallInitiator> ChaoticGoodServerTransport::ExtractStream( |
|
|
|
uint32_t stream_id) { |
|
|
|
uint32_t stream_id) { |
|
|
|
MutexLock lock(&mu_); |
|
|
|
|
|
|
|
GRPC_TRACE_LOG(chaotic_good, INFO) |
|
|
|
GRPC_TRACE_LOG(chaotic_good, INFO) |
|
|
|
<< "CHAOTIC_GOOD " << this << " ExtractStream " << stream_id; |
|
|
|
<< "CHAOTIC_GOOD " << this << " ExtractStream " << stream_id; |
|
|
|
|
|
|
|
MutexLock lock(&mu_); |
|
|
|
auto it = stream_map_.find(stream_id); |
|
|
|
auto it = stream_map_.find(stream_id); |
|
|
|
if (it == stream_map_.end()) return absl::nullopt; |
|
|
|
if (it == stream_map_.end()) return absl::nullopt; |
|
|
|
auto r = std::move(it->second); |
|
|
|
auto r = std::move(it->second); |
|
|
@ -433,12 +436,9 @@ absl::optional<CallInitiator> ChaoticGoodServerTransport::ExtractStream( |
|
|
|
|
|
|
|
|
|
|
|
absl::Status ChaoticGoodServerTransport::NewStream( |
|
|
|
absl::Status ChaoticGoodServerTransport::NewStream( |
|
|
|
uint32_t stream_id, CallInitiator call_initiator) { |
|
|
|
uint32_t stream_id, CallInitiator call_initiator) { |
|
|
|
MutexLock lock(&mu_); |
|
|
|
|
|
|
|
GRPC_TRACE_LOG(chaotic_good, INFO) |
|
|
|
GRPC_TRACE_LOG(chaotic_good, INFO) |
|
|
|
<< "CHAOTIC_GOOD " << this << " NewStream " << stream_id; |
|
|
|
<< "CHAOTIC_GOOD " << this << " NewStream " << stream_id; |
|
|
|
if (aborted_with_error_) { |
|
|
|
MutexLock lock(&mu_); |
|
|
|
return absl::UnavailableError("Transport closed"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
auto it = stream_map_.find(stream_id); |
|
|
|
auto it = stream_map_.find(stream_id); |
|
|
|
if (it != stream_map_.end()) { |
|
|
|
if (it != stream_map_.end()) { |
|
|
|
return absl::InternalError("Stream already exists"); |
|
|
|
return absl::InternalError("Stream already exists"); |
|
|
@ -454,7 +454,7 @@ absl::Status ChaoticGoodServerTransport::NewStream( |
|
|
|
self->ExtractStream(stream_id); |
|
|
|
self->ExtractStream(stream_id); |
|
|
|
if (call_initiator.has_value()) { |
|
|
|
if (call_initiator.has_value()) { |
|
|
|
auto c = std::move(*call_initiator); |
|
|
|
auto c = std::move(*call_initiator); |
|
|
|
c.SpawnInfallible("cancel_from_on_done", [c]() mutable { |
|
|
|
c.SpawnInfallible("cancel", [c]() mutable { |
|
|
|
c.Cancel(); |
|
|
|
c.Cancel(); |
|
|
|
return Empty{}; |
|
|
|
return Empty{}; |
|
|
|
}); |
|
|
|
}); |
|
|
|