Skip to content

client: fix result argument of wait #131

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

drewdzzz
Copy link
Collaborator

@drewdzzz drewdzzz commented Apr 23, 2025

The argument was completely broken - the commit fixes it.
Along the way, fixed a crash when a decoded future appeared in m_ReadyToDecode. See the commits for details.

Closes #112
Closes #124

@drewdzzz drewdzzz force-pushed the wait_with_response branch 4 times, most recently from d7df387 to abbe0c2 Compare April 24, 2025 08:39
@drewdzzz drewdzzz changed the title Wait with response client: fix result argument Apr 24, 2025
@drewdzzz drewdzzz changed the title client: fix result argument client: fix result argument of wait Apr 24, 2025
@drewdzzz drewdzzz force-pushed the wait_with_response branch 3 times, most recently from 2d9d6cc to 995d5ec Compare April 24, 2025 08:51
@drewdzzz
Copy link
Collaborator Author

Ignoring clang-format suggestions in order not to mess with the diff.
(I hope we'll do something about it sooner or later...)

Suggestions
diff --git a/src/Client/Connection.hpp b/src/Client/Connection.hpp
index d9626f0..30547e1 100644
--- a/src/Client/Connection.hpp
+++ b/src/Client/Connection.hpp
@@ -228,9 +228,8 @@ public:
 	friend
 	bool hasDataToDecode(Connection<B, N> &conn);
 
-	template<class B, class N>
-	friend
-	enum DecodeStatus processResponse(Connection<B, N> &conn, int req_sync, Response<B> *result);
+	template <class B, class N>
+	friend enum DecodeStatus processResponse(Connection<B, N> &conn, int req_sync, Response<B> *result);
 
 	template<class B, class N>
 	friend
@@ -527,7 +526,7 @@ inputBufGC(Connection<BUFFER, NetProvider> &conn)
 	}
 }
 
-template<class BUFFER, class NetProvider>
+template <class BUFFER, class NetProvider>
 DecodeStatus
 processResponse(Connection<BUFFER, NetProvider> &conn, int req_sync, Response<BUFFER> *result)
 {
diff --git a/src/Client/Connector.hpp b/src/Client/Connector.hpp
index 863bd28..c0db86e 100644
--- a/src/Client/Connector.hpp
+++ b/src/Client/Connector.hpp
@@ -171,7 +171,7 @@ Connector<BUFFER, NetProvider>::close(ConnectionImpl<BUFFER, NetProvider> &conn)
 	m_NetProvider.close(conn.strm);
 }
 
-template<class BUFFER, class NetProvider>
+template <class BUFFER, class NetProvider>
 int
 Connector<BUFFER, NetProvider>::connectionDecodeResponses(Connection<BUFFER, NetProvider> &conn, int req_sync,
 							  Response<BUFFER> *result)

@drewdzzz drewdzzz marked this pull request as ready for review April 24, 2025 11:05
@CuriousGeorgiy CuriousGeorgiy removed their assignment Apr 25, 2025
drewdzzz added 4 commits May 5, 2025 10:20
Connector uses a special helper for decoding responses of ready-to-decode
connections and then it erases them from `m_ReadyToDecode` set by himself.
That's not a good design and it can lead to various bugs (there is already
a bug, actually) because it's easy to forgot to erase a decoded connection.
So let's move the erasure right to the `connectionDecodeResponses` helper.
Note that the helper must be turned into a method of `Connector` since it
needs to use its fields.

The above-mentioned bug happens because we decode responses in
`Connector::wait` right before the main loop but we forgot to remove the
connection from `m_ReadyToDecode` set there.

Closes tarantool#124
Method `wait` of `Connector` allows to obtain result directly with
`result` argument - it can be useful when the user cares about
performance and don't want to perform an unneeded insertion to a map of
ready futures. However, we check that the future is ready by looking to
the map of ready futures, and the future is not inserted there when the
argument is used. The commit fixes the problem by checking the argument
as well.

Also, the commit handles a situation when user waits for already decoded
future using `result` argument. Before the commit, `wait` would return
zero return code (success) but the `result` wouldn't be set - user still
had to check if it's not in the map of futures. After the commit,
already decoded future is moved to `result` as well, so if the function
returns successfully, `result` is guaranteed to be set.

Part of tarantool#112
Somewhy we cast `nullptr` to the needed class when calling this function
and it looks ugly. Let's simply set default value of `result` to
`nullptr` not to pass it explicitly. Also, it will simplify the next
commit - we will add another optional argument to this function.
Currently, the argument returns any decoded future - that is
inconvenient and completely unusable. Let's return only the requested
future, or nothing, if it's not ready.

Along the way, reformat argument list of modified functions to make them
conform clang-format.

Closes tarantool#112
@CuriousGeorgiy CuriousGeorgiy removed their assignment May 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Calling waitAny after workload can break Tntcxx Potential error in wait
3 participants