pub(crate) struct ClientRequest<'req, 'handled> {
stream: DevtoolsConnection,
actor_name: &'req str,
handled: &'handled mut bool,
}Expand description
Wrapper around a client stream that guarantees request/reply invariants.
Client messages, which are always requests, are dispatched to Actor instances one at a time via
crate::Actor::handle_message. In most cases, each request must be paired with exactly one
reply from the same actor the request was sent to, where a reply is a message with no type. (If
a message from the server has a type, it’s a notification, not a reply).
Unless a request is of one of the few types considered “one-way”, failing to reply will almost
always permanently break that actor, because either the client gets stuck waiting for a reply,
or the client receives the reply for a subsequent request as if it was the reply for the current
request. If an actor fails to reply to a request, we want the dispatcher
(crate::ActorRegistry::handle_message) to send an error of type unrecognizedPacketType,
to keep the conversation for that actor in sync.
Since replies come in all shapes and sizes, we want to allow Actor types to send replies without
having to return them to the dispatcher. This wrapper type allows the dispatcher to check if a
valid reply was sent, and guarantees that if the actor tries to send a reply, it’s actually a
valid reply (see Self::is_valid_reply).
It does not currently guarantee anything about messages sent via the DevtoolsConnection
released via Self::stream or the return value of Self::reply.
Fields§
§stream: DevtoolsConnectionClient stream.
actor_name: &'req strExpected actor name.
handled: &'handled mut boolFlag allowing ActorRegistry to check for unhandled requests.
Implementations§
Source§impl ClientRequest<'_, '_>
impl ClientRequest<'_, '_>
Sourcepub fn handle<'req>(
stream: DevtoolsConnection,
actor_name: &'req str,
handler: impl FnOnce(ClientRequest<'req, '_>) -> Result<(), ActorError>,
) -> Result<(), ActorError>
pub fn handle<'req>( stream: DevtoolsConnection, actor_name: &'req str, handler: impl FnOnce(ClientRequest<'req, '_>) -> Result<(), ActorError>, ) -> Result<(), ActorError>
Run the given handler, with a new request that wraps the given client stream and expected actor name.
Returns ActorError::UnrecognizedPacketType if the actor did not send a reply.
Source§impl<'req> ClientRequest<'req, '_>
impl<'req> ClientRequest<'req, '_>
Sourcepub fn reply<T: Serialize>(self, reply: &T) -> Result<Self, ActorError>
pub fn reply<T: Serialize>(self, reply: &T) -> Result<Self, ActorError>
Send the given reply to the request being handled.
If successful, sets the sent flag and returns the underlying stream, allowing other messages to be sent after replying to a request.
Sourcepub fn reply_final<T: Serialize>(self, reply: &T) -> Result<(), ActorError>
pub fn reply_final<T: Serialize>(self, reply: &T) -> Result<(), ActorError>
Like reply, but for cases where the actor no longer needs the stream.
Sourcefn is_valid_reply<T: Serialize>(&self, message: &T) -> bool
fn is_valid_reply<T: Serialize>(&self, message: &T) -> bool
Return true iff the given message is a reply (has no type or to), and is from the expected actor.
This incurs a runtime conversion to a BTreeMap, so it should only be used in debug assertions.
Sourcepub fn mark_handled(self) -> Self
pub fn mark_handled(self) -> Self
Manually mark the request as handled, for one-way message types.
Sourcepub fn stream(&self) -> DevtoolsConnection
pub fn stream(&self) -> DevtoolsConnection
Get a copy of the client connection.
Trait Implementations§
Source§impl JsonPacketStream for ClientRequest<'_, '_>
Actors can also send other messages before replying to a request.
impl JsonPacketStream for ClientRequest<'_, '_>
Actors can also send other messages before replying to a request.
fn write_json_packet<T: Serialize>( &mut self, message: &T, ) -> Result<(), ActorError>
fn read_json_packet(&mut self) -> Result<Option<Value>, String>
Auto Trait Implementations§
impl<'req, 'handled> Freeze for ClientRequest<'req, 'handled>
impl<'req, 'handled> RefUnwindSafe for ClientRequest<'req, 'handled>
impl<'req, 'handled> Send for ClientRequest<'req, 'handled>
impl<'req, 'handled> Sync for ClientRequest<'req, 'handled>
impl<'req, 'handled> Unpin for ClientRequest<'req, 'handled>
impl<'req, 'handled> !UnwindSafe for ClientRequest<'req, 'handled>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more