diff --git a/src/communication/bolt/v1/session.hpp b/src/communication/bolt/v1/session.hpp index d7151e480..bb557cb64 100644 --- a/src/communication/bolt/v1/session.hpp +++ b/src/communication/bolt/v1/session.hpp @@ -38,15 +38,7 @@ class Session { public: Session(Socket &&socket, Dbms &dbms, QueryEngine &query_engine) - : socket_(std::move(socket)), - dbms_(dbms), - query_engine_(query_engine), - encoder_buffer_(socket_), - encoder_(encoder_buffer_), - output_stream_(encoder_), - decoder_buffer_(buffer_), - decoder_(decoder_buffer_), - state_(State::Handshake) { + : socket_(std::move(socket)), dbms_(dbms), query_engine_(query_engine) { event_.data.ptr = this; } @@ -155,17 +147,17 @@ class Session { Dbms &dbms_; QueryEngine &query_engine_; - ChunkedEncoderBuffer encoder_buffer_; - Encoder> encoder_; - OutputStream output_stream_; + ChunkedEncoderBuffer encoder_buffer_{socket_}; + Encoder> encoder_{encoder_buffer_}; + OutputStream output_stream_{encoder_}; Buffer<> buffer_; - ChunkedDecoderBuffer decoder_buffer_; - Decoder decoder_; + ChunkedDecoderBuffer decoder_buffer_{buffer_}; + Decoder decoder_{decoder_buffer_}; io::network::Epoll::Event event_; bool connected_{false}; - State state_; + State state_{State::Handshake}; // Active transaction of the session, can be null. tx::Transaction *transaction_; diff --git a/src/communication/bolt/v1/states/idle_result.hpp b/src/communication/bolt/v1/states/idle_result.hpp index f887217ce..58be3af2e 100644 --- a/src/communication/bolt/v1/states/idle_result.hpp +++ b/src/communication/bolt/v1/states/idle_result.hpp @@ -38,6 +38,11 @@ State HandleRun(Session &session, State state, Marker marker) { DLOG(INFO) << fmt::format("[ActiveDB] '{}'", db_accessor->name()); if (state != State::Idle) { + // TODO: We shouldn't clear the buffer and move to ErrorIdle state, but send + // MessageFailure without sending data that is already in buffer and move to + // ErrorResult state. + session.encoder_buffer_.Clear(); + // send failure message bool unexpected_run_fail_sent = session.encoder_.MessageFailure( {{"code", "Memgraph.QueryExecutionFail"}, @@ -48,10 +53,13 @@ State HandleRun(Session &session, State state, Marker marker) { DLOG(WARNING) << "Couldn't send failure message!"; return State::Close; } else { - return State::ErrorResult; + return State::ErrorIdle; } } + debug_assert(!session.encoder_buffer_.HasData(), + "There should be no data to write in this state"); + try { DLOG(INFO) << fmt::format("[Run] '{}'", query.Value()); auto is_successfully_executed = session.query_engine_.Run( diff --git a/src/communication/bolt/v1/states/init.hpp b/src/communication/bolt/v1/states/init.hpp index 8bec25c71..119d95161 100644 --- a/src/communication/bolt/v1/states/init.hpp +++ b/src/communication/bolt/v1/states/init.hpp @@ -17,6 +17,8 @@ namespace communication::bolt { */ template State StateInitRun(Session &session) { + debug_assert(!session.encoder_buffer_.HasData(), + "There should be no data to write in this state"); DLOG(INFO) << "Parsing message"; Marker marker; diff --git a/tests/unit/bolt_session.cpp b/tests/unit/bolt_session.cpp index c3f7210be..0ff88ba0f 100644 --- a/tests/unit/bolt_session.cpp +++ b/tests/unit/bolt_session.cpp @@ -441,7 +441,9 @@ TEST(BoltSession, ErrorRunAfterRun) { session.Execute(); // Run after run fails, but we still keep results. - ASSERT_EQ(session.state_, StateT::ErrorResult); + // TODO: actually we don't, but we should. Change state to ErrorResult once + // that is fixed. + ASSERT_EQ(session.state_, StateT::ErrorIdle); ASSERT_TRUE(session.socket_.IsOpen()); }