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

Little refactoring of locking logic #89

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

fatkodima
Copy link
Contributor

.timed method now is only concerned about just returning measured time.
And while not a real problem in this case, but refactored code avoids extra array allocation. Also it improves understandability and is more straightforward, as for me.

@coveralls
Copy link

coveralls commented Feb 6, 2020

Coverage Status

Coverage decreased (-5.07%) to 93.909% when pulling ca19abe on fatkodima:refactor-locking into 4075698 on leandromoreira:master.

Copy link
Collaborator

@maltoe maltoe left a comment

Choose a reason for hiding this comment

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

Thank you for your contributions, btw! 💚

I'll leave this as a comment for now, let's see what @leandromoreira says about the new style :)

@@ -42,7 +42,7 @@ def initialize(servers = DEFAULT_REDIS_URLS, options = {})
RedisInstance.new(server)
end
end
@quorum = (servers.length / 2).to_i + 1
@quorum = servers.length / 2 + 1
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍

time_elapsed = timed do
@servers.each do |server|
if server.lock(resource, value, ttl, allow_new_lock)
locked += 1
Copy link
Collaborator

Choose a reason for hiding this comment

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

TBH, I don't think this easier to read, especially mutating locked in an conditional.

If it's only about the timed function having 2 return values, you could still do

locked = 0
time_elapsed = timed do
  locked = @servers.select { |s| s.lock resource, value, ttl, allow_new_lock }.size
end

but on the other hand, maybe it's only me, and I wouldn't say I had a strong opinion on this one :) So if you insist, please go ahead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ya, one of the main reasons was 2 return values. Other, not critical in this case, is avoiding extra array allocation.
While original code is still very simple to understand it fast, personally I find it more clear when .select-like methods are using obvious explicit boolean-like methods inside it, like .locked? for example, to filter collection. And for doing something on collection, I would prefer just iterating using .each.

Copy link
Collaborator

Choose a reason for hiding this comment

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

hmm, so only .each may have side-effects? That's quite confining, isn't it?

How about

@servers.map { |s| s.lock resource, value, ttl, allow_new_lock }
                .select(&:itself)   # Or .select { |locked| locked }
                .size

wrt. to the extra array allocation: Seems a bit too detailed for me, without having any benchmarks/measurements.

But again, I don't have any strong opinions on any of this. Maybe @leandromoreira, but otherwise we can also just merge this in, from my pov.

Copy link
Owner

Choose a reason for hiding this comment

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

I'm with @maltoe I don't see any gains with this (without bench) refactoring and I think the old code is simpler.

Choose a reason for hiding this comment

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

FWIW There's is a .count method on arrays:

@servers.count{ |s| s.lock resource, value, ttl, allow_new_lock }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@maltoe Agreed with your initial comment, so updated taking it into account.

Copy link
Collaborator

@maltoe maltoe Dec 26, 2020

Choose a reason for hiding this comment

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

@kitsunde Yes, but [1, 2, false].count == 3

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When block is provided, count returns elements for which block evaluates to truthy value. So this suggestion is good here.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh nice, today I learned 👍

time_elapsed = timed do
@servers.each do |server|
if server.lock(resource, value, ttl, allow_new_lock)
locked += 1
Copy link
Owner

Choose a reason for hiding this comment

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

I'm with @maltoe I don't see any gains with this (without bench) refactoring and I think the old code is simpler.

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.

5 participants