Git Product home page Git Product logo

mongoid-locker's Introduction

Mongoid

This is the legacy fork which is no longer maintained. The official repository is now under the MongoDB organization here.

mongoid-locker's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mongoid-locker's Issues

Uninitialized Constant Mongoid::Locker

Hi There,

I am using 'mongoid-locker' gem in my rails application. and applied locker to my user model like below:

class User
  include Mongoid::Document
  include Mongoid::Timestamps
  include Mongoid::Locker

It is working fine when I applied locks for a transaction. but when I am trying to load user in console I am getting Uninitialized Constant Mongoid::Locker.

Any help would be appreciated.

Thank you in Advance.

Nesting of locks on same document

Hi, thanks for the awesome gem btw. Very impressive stuff.

One question I had was how to nest locks.

Let's say I have method that I usually call directly:

def a
  with_lock do
    ...   
  end
end

But I also have a method b that calls a and it does other stuff where I really need to start the lock sooner.

def b
  with_lock do
    # more stuff
    a
  end
end

It seems like a's lock would throw an exception or wait forever because it's already locked. Is there a good way to do this?

One thing I thought about was exposing the lock and unlocked methods themselves. Then I could doing something like lock unless locked? in a. Not sure how to release it cleanly though. Thanks for the help!

Cannot create TTL index on multiple fields in MongoDB 4.0 (as defined on the README.md file)

I have an index for a model that I want to use mongoid-locker with.

index({ _id: 1, locking_name: 1 }, name: 'mongoid_locker_index', sparse: true, unique: true, expire_after_seconds: lock_timeout)

When trying to create indexes I get this error:

Mongo::Error::OperationFailure:
  TTL indexes are single-field indexes, compound indexes do not support TTL. Index spec: { key: { _id: 1, locking_name: 1 }, name: "mongoid_locker_index", sparse: true, unique: true, expireAfterSeconds: 5 } (67) (on localhost:27017)

Should I be doing something different?

Versions:

mongoid-locker=2.0.1
mongoid=6.4.2
mongodb=4.0

add .unlocked scope

To query all documents in the collection that don't have a lock. Useful for a queue, to see what's available for processing.

Embed documents

I am trying to use your project with Embed documents

If I update embed document inside parent with with_lock it is not updated while saving parent
Parent embeds_many children. I take first of array and modify it with parent option

#self.with_lock do
child.status = 2
parent.option = 4
parent.save!
#end

I works with comment, but does not work without

Simultaneous actions resulting unknown results sometimes.

Hi There,

I am using Mongoid-locker gem to lock mongo document while writing data simultaneously.
I have a concept of sending amount from one user to other user in my app. I have field named "Balance" in my "User" Table
Example: Two Users A, B
My Scenario: Sending amount from A to B one after other working properly and it is fine. But when I am trying the same simultaneously sometimes amount are deducting/adding properly but sometimes it is failing.

I have added with_lock for both receiver and sender with option wait: true.

I am thinking that we can do something like if we know that document is locked, then we can stop that transaction but I don't know how to check whether document gets locked or not.

Could you please assist me to solve this

undefined method `-' for nil:NilClass

In the current HEAD version, I get undefined method - for nil:NilClass when calling

self.with_lock timeout: 1.minute, wait: true, reload: true do

My backtrace is:

/Users/me/.rvm/gems/ruby-1.9.3-p392/bundler/gems/mongoid-locker-19e6fccd5e38/lib/mongoid/locker.rb:143:in `lock'
/Users/me/.rvm/gems/ruby-1.9.3-p392/bundler/gems/mongoid-locker-19e6fccd5e38/lib/mongoid/locker.rb:79:in `with_lock'
/Users/me/Documents/Projects/priceapi_api/app/models/job.rb:89:in `handle_result'

This is the line

retry_sleep = locked_until - Time.now

Which means, that locked_until is nil here.

incompatible with Mongoid version `v7.0`

mongoid has release a new version: v7.0 at 2018-3-12

but there have not a hight version limit for mongoid-lock, and only support v2 to v6 in lib/mongoid/locker/wrapper.rb

RuntimeError:
  incompatible Mongoid version
# /usr/local/lib/ruby/gems/2.4.0/gems/mongoid-locker-0.3.5/lib/mongoid/locker/wrapper.rb:14:in `<top (required)>'

Race condition under load

We noticed that under load, mongoid locker allows more than one thread to enter a critical section. The issue can be reproduced using this repository that contains full description of the scenario.

During the investigation we removed mongoid-locker and mongoid and reproduced the issues. It means that the bug is not in the mongoid-locker itself. It breaks the mongoid-locker though. It's reported in mongo ruby driver tracker, I'm writing to make you aware of the issue.

I also provided a simpler lock implementation based on expiring and unique indices. It passes our test and cause no issues on production.

on collections sharded by "_id", Mongoid::Locker can't get a lock

(at least in my production environment)
On any collection sharded by the shard key "_id", this code

2.0.0p247 :001 > i = Item.first
2.0.0p247 :002 > i.with_lock do
2.0.0p247 :003 >     puts i.inspect
2.0.0p247 :004?>   end

throws the exception "Mongoid::Locker::LockError: could not get lock"
from line 148 in lib/mongoid/locker.rb 'lock'

a collection sharded by some other key doesn't seem to have this problem, nor does an unsharded collection.

mongoid 7.1.0 issue with arguments

something stopped working with mongoid 7.1.0 gem release. It was still fine with 7.1.0.rc0

irb(main):001:0> Address.last
Traceback (most recent call last):
        4: from (irb):1
        3: from app/models/address.rb:3:in `<main>'
        2: from app/models/address.rb:8:in `<class:Address>'
        1: from app/models/address.rb:8:in `include'
ArgumentError (wrong number of arguments (given 7, expected 1))

address.rb

# frozen_string_literal: true

class Address
  # == Inclusions ===========================================================

  include Mongoid::Document
  include Mongoid::Timestamps
  include Mongoid::Locker

Add example on how to write specs on operations that rely on Mongoid Lock to be safe

It would be convenient to have some examples of specs that validate race conditions.

For instance, how do I write a spec for the following service assuming 2 servers perform an operation that should be unsafe without Mongoid Lock, and safe with it, like withdrawing cash from an account ?

class MyService
  def call(user:, cash_to_withdraw:)
    # user.with_lock do # how do I write a spec that fails without this wrapper ?
      if user.has_enough_cash_for(cash_to_withdraw)
        user.withdraw_cash!(cash_to_withdraw)
      end
    # end
  end
end

It would be nice to have examples using RSpec or any other framework, or maybe a custom spec framework specialized in concurrency tests.

Is Jux working?

The need arose at Jux from multiple processes on multiple servers trying to act upon the same document and stepping on each other's toes.

We can remove the sentence from README if Jux project is dead.

Incompatible with Mongoid 3.1.6

Hi all,

I have a problem trying to install mongoid-locker gem in my project. I'm using Mongoid(3.1.6).
If I add this to my gemfile:

gem 'mongoid-locker', '~> 0.2'

I get this error

Bundler could not find compatible versions for gem "mongoid":
  In Gemfile:
    mongoid-locker (~> 0.2) ruby depends on
      mongoid (<= 3.1, >= 2.4) ruby

    mongoid (3.1.6)

And if I point to the newer versions in my Gemfile:

gem 'mongoid-locker', '~> 0.3'

I get this error

Bundler could not find compatible versions for gem "mongoid":
  In Gemfile:
    mongoid-locker (~> 0.3) ruby depends on
      mongoid (~> 4.0) ruby

    mongoid (3.1.6)

We're not planning to upgrade to Mongoid 4 yet, so I'd like to use the version ~> 0.2. I was looking into this problem and I found this issue https://github.com/afeld/mongoid-locker/issues/12 that seems to be the solution. However, if it was the solution before it's not working anymore.

I can create a PR to support Mongoid versions ~> 3.1.0 but I want to be sure I'm not missing something.

Thanks in advance,
Francisco.

reload after waiting

If they have to wait for a lock, the document was probably modified, so it should probably #reload afterwards. Not sure how modified attributes are handled, though.

Add danger

Just like for other mongoid org projects, add mongoid-danger.

Update the RubyGems version

The current rubygems version does not support mongoid 4

It would be convenient if the latest version, which seems to work fine with mongoid 4, would make it's way to rubygems.

Mongoid recently updated their rubgems version to Mongoid 4 so it should work.

fix for subclasses

The following fails with can't convert nil into an exact number:

class User
  include Mongoid::Document
  include Mongoid::Locker
end

class Admin < User
end

Admin.last.with_lock { ... }

throws exception when not locked

in locker.rb

unless opts[:retry_sleep]
            locked_until = Mongoid::Locker::Wrapper.locked_until(self)
            retry_sleep = locked_until - Time.now
end

but locked_until can (and does) return nil if not locked. So locked_until - Time.now throws error.

Sorry, no patch as I'm not that familiar with mongo + locker

Allow customizing locked_at field (clash with Devise).

mongoid-locker uses hardcoded field name :locked_at. This is also the name that is hardcoded into Devise::Lockable module.

In our app that led to a nasty bug where users would be spontaneously logged out. Very annoying.

I tried to make the field configurable but I hated the result (code becomes quite uglier). So I won't be posting a PR now, I'm afraid.

In our app I fixed it by forking and hardcode-renaming the field: https://github.com/stulentsev/mongoid-locker/tree/alternate_field

A clash with such popular gem as Devise should be a serious problem. I'm actually surprised it didn't surface earlier.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.