Refactored bolt session to use new decoder.
Summary: Bolt buffer is now a template. Communication worker now has a new interface. Fixed network tests to use new interface. Fixed bolt tests to use new interface. Added more functions to bolt decoder. Reviewers: dgleich, buda Reviewed By: buda Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D256
This commit is contained in:
@@ -1,38 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include "communication/bolt/v1/messaging/codes.hpp"
|
||||
#include "communication/bolt/v1/codes.hpp"
|
||||
#include "communication/bolt/v1/state.hpp"
|
||||
#include "logging/default.hpp"
|
||||
|
||||
namespace communication::bolt {
|
||||
|
||||
/**
|
||||
* TODO (mferencevic): finish & document
|
||||
* 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 Session>
|
||||
State StateErrorRun(Session &session) {
|
||||
static Logger logger = logging::log->logger("State ERROR");
|
||||
|
||||
session.decoder_.read_byte();
|
||||
auto message_type = session.decoder_.read_byte();
|
||||
|
||||
logger.trace("Message type byte is: {:02X}", message_type);
|
||||
|
||||
if (message_type == MessageCode::PullAll) {
|
||||
session.encoder_.MessageIgnored();
|
||||
return ERROR;
|
||||
} else if (message_type == MessageCode::AckFailure) {
|
||||
// TODO reset current statement? is it even necessary?
|
||||
logger.trace("AckFailure received");
|
||||
session.encoder_.MessageSuccess();
|
||||
return EXECUTOR;
|
||||
} else if (message_type == MessageCode::Reset) {
|
||||
// TODO rollback current transaction
|
||||
// discard all records waiting to be sent
|
||||
session.encoder_.MessageSuccess();
|
||||
return EXECUTOR;
|
||||
Marker marker;
|
||||
Signature signature;
|
||||
if (!session.decoder_.ReadMessageHeader(&signature, &marker)) {
|
||||
logger.debug("Missing header data!");
|
||||
return State::Close;
|
||||
}
|
||||
|
||||
logger.trace("Message signature is: 0x{:02X}", underlying_cast(signature));
|
||||
|
||||
// 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)
|
||||
logger.trace("AckFailure received");
|
||||
else
|
||||
logger.trace("Reset received");
|
||||
|
||||
if (!session.encoder_.MessageSuccess()) {
|
||||
logger.debug("Couldn't send success message!");
|
||||
return State::Close;
|
||||
}
|
||||
return State::Executor;
|
||||
} else {
|
||||
uint8_t value = underlying_cast(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) != underlying_cast(Marker::TinyStruct)) {
|
||||
logger.debug("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
|
||||
query::TypedValue tv;
|
||||
for (int i = 0; i < value; ++i) {
|
||||
if (!session.decoder_.ReadTypedValue(&tv)) {
|
||||
logger.debug("Couldn't clean up parameter {} / {}!", i, value);
|
||||
return State::Close;
|
||||
}
|
||||
}
|
||||
|
||||
// ignore this message
|
||||
if (!session.encoder_.MessageIgnored()) {
|
||||
logger.debug("Couldn't send ignored message!");
|
||||
return State::Close;
|
||||
}
|
||||
|
||||
// cleanup done, command ignored, stay in error state
|
||||
return State::Error;
|
||||
}
|
||||
session.encoder_.MessageIgnored();
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user