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

Feature request: allow lock! to be extended #84

Open
nikolai-b opened this issue Nov 21, 2019 · 3 comments
Open

Feature request: allow lock! to be extended #84

nikolai-b opened this issue Nov 21, 2019 · 3 comments

Comments

@nikolai-b
Copy link
Contributor

I would like to extend a lock!

Would you consider making lock! return the lock_info and also allow it to be called without a block, e.g.

def lock!(*args)
  lock(*args) do |lock_info|
    raise LockError, 'failed to acquire lock' unless lock_info
    if block_given?
      yield lock_info
    else
      lock_info
    end
  end
end
@maltoe
Copy link
Collaborator

maltoe commented Nov 21, 2019

@nikolai-b Not sure I understand, what's the difference to lock() then? If it's only about the raise on error, why not do

lock_info = client.lock(...)
raise Redlock::LockError unless lock_info

?

@nikolai-b
Copy link
Contributor Author

No real difference, just often in rails bang methods do the same thing but raise instead of returning false / nil.

> User.find_by(id: 1)
=> nil
> User.find_by!(id: 1)
=> ActiveRecord::RecordNotFound: Couldn't find User

I understand that in ruby core the bang means it modifies the receiver.

Yes I can do what you suggest if you prefer to keep the lock! method having a different pattern but it surprised me and stops lock! being able to be extended.

@maltoe
Copy link
Collaborator

maltoe commented Nov 21, 2019

Hmm, the original implementation of this dates back before I stumbled into this gem :)

I see what you mean now, and agree that the behaviour of lock/lock! is a bit confusing. TBH, I think the lock function probably just shouldn't accept a block at all (as when you call it with a block and don't validate the result, you're not sure the block was called at all), but that's probably a different matter.

So yes, if you think this is needed, please come up with a PR for it. Please be aware though lock() with a block given will unlock the resource when the block exits, so the implementation would need to look more like:

def lock!(*args)
  if block_given?
    lock(*args).tap { |lock_info| raise ... unless lock_info }
  else
    lock(*args) do |lock_info|
      raise ... unless lock_info
      yield
    end
  end
end

Not sure if it's really worth it..

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

No branches or pull requests

2 participants