Skip to content

Merge feature branch "Single process client"#165

Open
zuiderkwast wants to merge 3 commits intomainfrom
single-process-client
Open

Merge feature branch "Single process client"#165
zuiderkwast wants to merge 3 commits intomainfrom
single-process-client

Conversation

@zuiderkwast
Copy link
Copy Markdown
Collaborator

  • Merge ered_client and ered_connection (reduces the number of processes from 3 to 1 per connection)
  • Send commands in batches
  • Non-blocking send

zuiderkwast and others added 3 commits April 2, 2026 16:26
* Get rid of the two processes in ered_connection and duplicated logic.
* Use active mode.
* Response timeout handling is existing but incomplete.
* Batching is not fixed. Only sends one command at a time.
* Sending may block. The client process is unresponsive when it happens.

Batching and non-blocking send are to be fixed in follow-up PRs.

---------

Signed-off-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
When the pending queue is full, don't send more commands until the
pending queue can fit another batch of commands, as configured with the
existing config `batch_size`.

The purpose is to improve performance by sending fewer and larger TCP
packets.

The config for `batch_size` has existed before but the batching
functionality has not worked properly.

Bonus: Use assert macros instead of direct pattern matching in eunit
tests to verify output/input, to get better error messages on failure.

---------

Co-authored-by: William Voong <william.voong@ericsson.com>
Co-authored-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
Use send_timeout 0. If send returns timeout, it has still queued all the
data for sending later. When this happens, backoff and don't send more
to the socket until the pending commands have got replies from the
server. This requires that gen_tcp is used with the inet backend (the
default) and not the socket backend.

With TLS, this approach works in older OTP versions, but it was broken
for TLS in OTP 28.0 - 28.4, but fixed again in 28.4.1 (OTP-20018).

If we need to support these OTP versions, or if we want to suppor
gen_tcp with the socket backend or the socket module directly, we can
implement more variants later.

---------

Signed-off-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
Co-authored-by: Hippo <44473866+WilliamVoong@users.noreply.github.com>
@zuiderkwast zuiderkwast requested a review from WilliamVoong April 2, 2026 14:29
Comment on lines +814 to +818
response_timeout(State) when not ?q_is_empty(State#st.pending) ->
%% FIXME: Store req timeout in each pending item
State#st.opts#opts.timeout;
response_timeout(_State) ->
infinity.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Many functions such as handle_cast return this timeout in the element in the type, such as {noreply, State, response_timeout(State)}.

This is quite simplistic, since it will effectively reset the timeout every time there is any interaction with the process, including sending more to the server.

Storing a response timeout timestamp per pending request would be the most exact handling, but maybe it's overkill?

Another approach is to have a single timestamp and reset it only whenever we get a response from the server. Then, this timeout effectively limits how long we're waiting between each response.

This depends very much on your requirements. @WilliamVoong please find out. 😄

@zuiderkwast zuiderkwast requested a review from JeppeTh April 2, 2026 14:44
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.

2 participants