Reviewers: teon.banek Reviewed By: teon.banek Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D1506
83 lines
2.5 KiB
C++
83 lines
2.5 KiB
C++
#pragma once
|
|
|
|
#include <fmt/format.h>
|
|
#include <glog/logging.h>
|
|
|
|
#include "communication/bolt/v1/codes.hpp"
|
|
#include "communication/bolt/v1/state.hpp"
|
|
#include "communication/bolt/v1/value.hpp"
|
|
#include "utils/cast.hpp"
|
|
|
|
namespace communication::bolt {
|
|
|
|
/**
|
|
* Error state run function
|
|
* This function handles a Bolt session when it is in an error state.
|
|
* The error state is exited upon receiving an ACK_FAILURE or RESET message.
|
|
* @param session the session that should be used for the run
|
|
*/
|
|
template <typename TSession>
|
|
State StateErrorRun(TSession &session, State state) {
|
|
Marker marker;
|
|
Signature signature;
|
|
if (!session.decoder_.ReadMessageHeader(&signature, &marker)) {
|
|
DLOG(WARNING) << "Missing header data!";
|
|
return State::Close;
|
|
}
|
|
|
|
// Clear the data buffer if it has any leftover data.
|
|
session.encoder_buffer_.Clear();
|
|
|
|
if (signature == Signature::AckFailure || signature == Signature::Reset) {
|
|
if (signature == Signature::AckFailure) {
|
|
DLOG(INFO) << "AckFailure received";
|
|
} else {
|
|
DLOG(INFO) << "Reset received";
|
|
}
|
|
|
|
if (!session.encoder_.MessageSuccess()) {
|
|
DLOG(WARNING) << "Couldn't send success message!";
|
|
return State::Close;
|
|
}
|
|
if (signature == Signature::Reset) {
|
|
session.Abort();
|
|
return State::Idle;
|
|
}
|
|
|
|
// We got AckFailure get back to right state.
|
|
CHECK(state == State::Error) << "Shouldn't happen";
|
|
return State::Idle;
|
|
} else {
|
|
uint8_t value = utils::UnderlyingCast(marker);
|
|
|
|
// All bolt client messages have less than 15 parameters so if we receive
|
|
// anything than a TinyStruct it's an error.
|
|
if ((value & 0xF0) != utils::UnderlyingCast(Marker::TinyStruct)) {
|
|
DLOG(WARNING) << fmt::format(
|
|
"Expected TinyStruct marker, but received 0x{:02X}!", value);
|
|
return State::Close;
|
|
}
|
|
|
|
// We need to clean up all parameters from this command.
|
|
value &= 0x0F; // The length is stored in the lower nibble.
|
|
Value dv;
|
|
for (int i = 0; i < value; ++i) {
|
|
if (!session.decoder_.ReadValue(&dv)) {
|
|
DLOG(WARNING) << fmt::format("Couldn't clean up parameter {} / {}!", i,
|
|
value);
|
|
return State::Close;
|
|
}
|
|
}
|
|
|
|
// Ignore this message.
|
|
if (!session.encoder_.MessageIgnored()) {
|
|
DLOG(WARNING) << "Couldn't send ignored message!";
|
|
return State::Close;
|
|
}
|
|
|
|
// Cleanup done, command ignored, stay in error state.
|
|
return state;
|
|
}
|
|
}
|
|
} // namespace communication::bolt
|