use std::collections::HashMap;
use cheetah_string::CheetahString;
use rocketmq_protocol::protocol::remoting_command::RemotingCommand;
use super::request_control::LazyExtensions;
use super::AuthenticationState;
use super::DeferredResponderOutcome;
use super::InlineResponseSlot;
use super::OriginalRequestIdentity;
use super::ProtocolNoResponse;
use super::ProtocolNoResponseReason;
use super::RequestControlView;
use super::RequestMeta;
use super::RequestOrigin;
use super::ResponseAction;
use crate::contract::TransportContractViolation;
use crate::session_view::SessionView;
mod builder;
pub(crate) use builder::RemotingRequestBuilder;
pub(crate) use builder::RequestLifecycleProvenance;
pub struct RemotingRequest {
original: OriginalRequestIdentity,
meta: RequestMeta,
origin: RequestOrigin,
authentication: AuthenticationState,
session: SessionView,
control: RequestControlView,
extensions: LazyExtensions,
inline_response: InlineResponseSlot,
command: RemotingCommand,
}
impl RemotingRequest {
#[must_use]
pub const fn original_identity(&self) -> OriginalRequestIdentity {
self.original
}
#[must_use]
pub const fn meta(&self) -> &RequestMeta {
&self.meta
}
#[must_use]
pub const fn origin(&self) -> &RequestOrigin {
&self.origin
}
#[must_use]
pub const fn authentication(&self) -> &AuthenticationState {
&self.authentication
}
#[must_use]
pub const fn session(&self) -> &SessionView {
&self.session
}
#[must_use]
pub const fn control(&self) -> &RequestControlView {
&self.control
}
pub fn protocol_no_response(
&self,
reason: ProtocolNoResponseReason,
) -> Result<ProtocolNoResponse, TransportContractViolation> {
ProtocolNoResponse::from_original(self.original, reason)
}
pub fn take_deferred_responder(&mut self) -> DeferredResponderOutcome {
self.inline_response.take_deferred_responder(self.original)
}
#[must_use]
pub const fn command(&self) -> &RemotingCommand {
&self.command
}
pub fn command_mut(&mut self) -> &mut RemotingCommand {
&mut self.command
}
#[must_use]
pub fn extension<T>(&self) -> Option<&T>
where
T: Send + Sync + 'static,
{
self.extensions.get()
}
pub fn try_insert_extension<T>(&mut self, value: T) -> Result<Option<T>, T>
where
T: Send + Sync + 'static,
{
self.extensions.try_insert(value)
}
#[cfg(test)]
pub(crate) const fn has_reserved_deferred_response(&self) -> bool {
self.inline_response.has_deferred_capability()
}
#[cfg(test)]
pub(crate) fn mark_deferred_response_taken(&mut self) -> Result<(), TransportContractViolation> {
self.inline_response.mark_deferred_taken(self.original)
}
pub(crate) fn resolve_response_action(
&mut self,
outcome: ResponseAction,
) -> Result<ResponseAction, TransportContractViolation> {
self.inline_response.resolve(self.original, outcome)
}
pub(crate) fn consume_oneway_deferred(
&mut self,
registration: crate::dispatch::DeferredRegistration,
) -> Result<(), TransportContractViolation> {
self.inline_response
.consume_oneway_deferred(self.original, registration)
}
pub(crate) fn consume_oneway_no_reply(
&mut self,
marker: crate::dispatch::ProtocolNoResponse,
) -> Result<(), TransportContractViolation> {
self.inline_response.consume_oneway_no_reply(self.original, marker)
}
pub(crate) fn with_body_free_hook_command<T>(
&mut self,
apply: impl FnOnce(&mut RemotingCommand) -> Result<T, rocketmq_error::SharedError>,
) -> Result<T, rocketmq_error::SharedError> {
let body = self.command.take_body();
let result = apply(&mut self.command);
let attached_body = self.command.take_body();
if let Some(body) = body {
self.command.set_body_mut_ref(body);
}
if attached_body.is_some() {
return Err(crate::error_helpers::invariant_violated());
}
result
}
pub(crate) fn with_body_free_hook_request<T>(
&mut self,
apply: impl FnOnce(&RemotingCommand) -> Result<T, rocketmq_error::SharedError>,
) -> Result<T, rocketmq_error::SharedError> {
let body = self.command.take_body();
let result = apply(&self.command);
debug_assert!(self.command.body().is_none());
if let Some(body) = body {
self.command.set_body_mut_ref(body);
}
result
}
}
pub struct IngressRequestView<'a> {
original: OriginalRequestIdentity,
ext_fields: Option<&'a HashMap<CheetahString, CheetahString>>,
}
impl<'a> IngressRequestView<'a> {
#[must_use]
pub const fn original_identity(&self) -> OriginalRequestIdentity {
self.original
}
#[must_use]
pub const fn ext_fields(&self) -> Option<&'a HashMap<CheetahString, CheetahString>> {
self.ext_fields
}
}
pub(crate) type DeferredSlot = InlineResponseSlot;
#[cfg(test)]
#[path = "../../tests/unit/dispatch/remoting_request.rs"]
mod tests;