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:
Matej Ferencevic
2017-04-15 15:14:12 +02:00
parent db30e72069
commit f05fcd91c3
39 changed files with 1260 additions and 1112 deletions

View File

@@ -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;
}
}