Skip to content
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

Implement send_request as in gen_server #187

Merged
merged 6 commits into from
Jan 7, 2022
Merged

Conversation

NelsonVides
Copy link
Collaborator

Since OTP23, gen_server exposes some kind of "asynchronous calls", that is, a mechanism to make a call, and do other stuff while we wait for the result. send_request returns a reference, that can be used to match any incoming answers later on, either using gen_server:wait_for_response/2, or to do gen_server:check_response/2 for any message received in a receive statement or a handle_info clause.

See some commit messages for details.

An important change is actually how the queue manager does the call: the
client would send a call to the queue manager with the whole request,
and the queue manager would then do a cast_call to the worker with the
whole request again, incurring in two copies of the request on each
erlang message send, which, for very big payloads, can mean lots of
copying. Now, the client, within the queue manager's API, calls the
queue manager for an available worker, and when it gets it, calls the
worker with the whole payload, doing the copies only once. This also
uncovers crashes that could happen for other strategies, that wouldn't
happen for the available_worker one as it was doing a very wide catch.
This takes the already consumed time away from the next timeout.
Since OTP23, `gen_server` exposes some kind of "asynchronous calls",
that is, a mechanism to make a call, and do other stuff while we wait
for the result. `send_request` returns a reference, that can be used to
match any incoming answers later on, either using
`gen_server:wait_for_response/2`, or to do `gen_server:check_response/2`
for any message received in a `receive` statement or a `handle_info`
clause.
@codecov
Copy link

codecov bot commented Jan 5, 2022

Codecov Report

Merging #187 (5df77cf) into main (6275bfc) will decrease coverage by 0.72%.
The diff coverage is 83.33%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #187      +/-   ##
==========================================
- Coverage   92.82%   92.09%   -0.73%     
==========================================
  Files          10       10              
  Lines         432      443      +11     
==========================================
+ Hits          401      408       +7     
- Misses         31       35       +4     
Impacted Files Coverage Δ
src/wpool_queue_manager.erl 86.66% <81.48%> (-1.80%) ⬇️
src/wpool.erl 97.29% <83.33%> (-2.71%) ⬇️
src/wpool_pool.erl 96.40% <100.00%> (+0.02%) ⬆️
src/wpool_process.erl 80.51% <100.00%> (-1.84%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 6275bfc...5df77cf. Read the comment docs.

Comment on lines -60 to -63
%% @equiv gen_server:cast(Process, {call, From, Call})
-spec cast_call(wpool:name() | pid(), from(), term()) -> ok.
cast_call(Process, From, Call) ->
gen_server:cast(Process, {call, From, Call}).
Copy link
Member

Choose a reason for hiding this comment

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

WOW! I didn't realize we could already remove this super-annoying function. Amazing!

Copy link
Member

@elbrujohalcon elbrujohalcon left a comment

Choose a reason for hiding this comment

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

I like this in general.
I don't fully grasp what you did with the expiration and timeouts. It seems that you simplified the code and I trust you, tho. So, I like it.
I left a super-minor stylistic change request, too.

Comment on lines 64 to 65
{ok, TimeLeft, Worker} ->
case TimeLeft > 0 of
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
{ok, TimeLeft, Worker} ->
case TimeLeft > 0 of
{ok, TimeLeft, Worker} when TimeLeft > 0 ->

@NelsonVides
Copy link
Collaborator Author

I like this in general. I don't fully grasp what you did with the expiration and timeouts. It seems that you simplified the code and I trust you, tho. So, I like it. I left a super-minor stylistic change request, too.

Stylistic change, ag, fixed, thanks for noticing!

The expiration timeouts, there's basically two steps going on: finding the available worker, and once we have it, calling it. Those are two conceptually separated steps, but the second will have less time available for itself: the amount of time the first had already consumed, therefore the substraction. Then we just need to check, after the substraction, if we still have available time.

Before, the whole request was run on the context of the queue manager. Now, the client asks the queue manager for a worker, and then the client sends the request himself to the worker, timeouts fixed.

@elbrujohalcon
Copy link
Member

Considering #98 … I would merge this even with the coverage reduction.

@elbrujohalcon elbrujohalcon merged commit df43aad into main Jan 7, 2022
@elbrujohalcon elbrujohalcon deleted the implement_send_request branch January 7, 2022 09:17
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