Uploaded image for project: 'Mongoid'
  1. Mongoid
  2. MONGOID-3933

Can't nest `atomically` blocks

    • Type: Icon: Task Task
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • 5.1.0
    • Affects Version/s: None
    • Component/s: None
    • None

      Hi, currently if you try to nest atomically blocks even on a single object Mongoid fails with an awful error.

      Below script that shows this behavior and it's output. In the output you can see that Mongoid is trying to execute an empty update operation.

       ruby
      require 'mongoid'
      
      Mongoid.configure {|c| c.connect_to "test"}
      
      puts "Using Mongoid #{Mongoid::VERSION}"
      
      class Assignment
        include Mongoid::Document
      
        field :external_1, type: Integer, default: 0
        field :external_2, type: Integer, default: 0
        field :internal_1, type: Array
        field :internal_2, type: Mongoid::Boolean, default: true
      
        def my_push value
          atomically do
            add_to_set internal_1: value
            unset :internal_2
          end
        end
      end
      Assignment.delete_all
      
      Moped.logger = Logger.new(STDOUT)
      
      assignment = Assignment.create
      assignment.atomically do |a|
        a.inc external_1: 2
        a.inc external_2: 4
        a.my_push "qwe"
      end
      
      mongoid-errors$ruby nested_atomically.rb 
      Using Mongoid 4.0.1
      D, [2015-01-30T01:35:02.833221 #7624] DEBUG -- :   MOPED: 127.0.0.1:27017 INSERT       database=test collection=assignments documents=[{"_id"=>BSON::ObjectId('54cad1b64164611dc8000000'), "external_1"=>0, "external_2"=>0, "internal_2"=>true}] flags=[]
      D, [2015-01-30T01:35:02.833285 #7624] DEBUG -- :                          COMMAND      database=test command={:getlasterror=>1, :w=>1} runtime: 0.2760ms
      D, [2015-01-30T01:35:02.833866 #7624] DEBUG -- :   MOPED: 127.0.0.1:27017 UPDATE       database=test collection=assignments selector={"_id"=>BSON::ObjectId('54cad1b64164611dc8000000')} update={"$addToSet"=>{"internal_1"=>{"$each"=>["qwe"]}}, "$unset"=>{"internal_2"=>true}} flags=[]
      D, [2015-01-30T01:35:02.833898 #7624] DEBUG -- :                          COMMAND      database=test command={:getlasterror=>1, :w=>1} runtime: 0.2960ms
      D, [2015-01-30T01:35:02.835907 #7624] DEBUG -- :   MOPED: 127.0.0.1:27017 UPDATE       database=test collection=assignments selector={"_id"=>BSON::ObjectId('54cad1b64164611dc8000000')} update=nil flags=[]
      D, [2015-01-30T01:35:02.835944 #7624] DEBUG -- :                          COMMAND      database=test command={:getlasterror=>1, :w=>1} runtime: 1.8620ms
      /usr/local/lib/ruby/gems/2.2.0/gems/moped-2.0.3/lib/moped/operation/read.rb:50:in `block in execute': The operation: #<Moped::Protocol::Command (Moped::Errors::OperationFailure)
        @length=68
        @request_id=10
        @response_to=0
        @op_code=2004
        @flags=[]
        @full_collection_name="test.$cmd"
        @skip=0
        @limit=-1
        @selector={:getlasterror=>1, :w=>1}
        @fields=nil>
      failed with error "d.moreJSObjs()"
      	from /usr/local/lib/ruby/gems/2.2.0/gems/moped-2.0.3/lib/moped/node.rb:594:in `[]'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/moped-2.0.3/lib/moped/node.rb:594:in `block (2 levels) in flush'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/moped-2.0.3/lib/moped/node.rb:593:in `map'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/moped-2.0.3/lib/moped/node.rb:593:in `block in flush'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/moped-2.0.3/lib/moped/node.rb:617:in `block in logging'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/notifications.rb:164:in `block in instrument'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/notifications.rb:164:in `instrument'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/moped-2.0.3/lib/moped/instrumentable.rb:31:in `instrument'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/moped-2.0.3/lib/moped/node.rb:616:in `logging'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/moped-2.0.3/lib/moped/node.rb:587:in `flush'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/moped-2.0.3/lib/moped/node.rb:358:in `pipeline'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/moped-2.0.3/lib/moped/operation/write.rb:47:in `execute'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/moped-2.0.3/lib/moped/node.rb:665:in `write'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/moped-2.0.3/lib/moped/node.rb:502:in `update'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/moped-2.0.3/lib/moped/query.rb:427:in `block in update'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/moped-2.0.3/lib/moped/cluster.rb:249:in `block in with_primary'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/moped-2.0.3/lib/moped/node.rb:204:in `block in ensure_primary'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/moped-2.0.3/lib/moped/executable.rb:25:in `execute'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/moped-2.0.3/lib/moped/node.rb:203:in `ensure_primary'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/moped-2.0.3/lib/moped/cluster.rb:248:in `with_primary'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/moped-2.0.3/lib/moped/query.rb:426:in `update'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/mongoid-4.0.1/lib/mongoid/query_cache.rb:117:in `update_with_clear_cache'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/mongoid-4.0.1/lib/mongoid/persistable.rb:212:in `persist_atomic_operations'
      	from /usr/local/lib/ruby/gems/2.2.0/gems/mongoid-4.0.1/lib/mongoid/persistable.rb:60:in `atomically'
      	from nested_atomically.rb:27:in `<main>'
      

            Assignee:
            Unassigned Unassigned
            Reporter:
            amw Adam Wróbel
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: