Uploaded image for project: 'Ruby Driver'
  1. Ruby Driver
  2. RUBY-2151

BSON Time Objects

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: bson-4.8.0
    • Component/s: BSON
    • None

      We noticed some test failures on our RubyGem builds surrounding a feature of our platform, which uses MongoDB aggregations to provide reports and insights for the various models in our system. Most of the tests that failed were testing for values in a date range, which was seemingly inaccurate by a few hours. These tests began failing on the day that v4.8.0 of the bson gem was released, and by locking down to v4.7.1, we were able to get back to a stable build. After doing this, I dug in a little further and found that the following change happened to the BSON::Time module as a result of the update:

       

          # Get the time as encoded BSON.
          #
          # @example Get the time as encoded BSON.
          #   Time.new(2012, 1, 1, 0, 0, 0).to_bson
          #
          # @return [ BSON::ByteBuffer ] The buffer with the encoded object.
          #
          # @see http://bsonspec.org/#/specification
          #
          # @since 2.0.0
          def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
            # A previous version of this method used the following implementation:
            # buffer.put_int64((to_i * 1000) + (usec / 1000))
            # Turns out, usec returned incorrect value - 999 for 1 millisecond.
            buffer.put_int64((to_f * 1000).round)
          end
      

      When changing this back to its original implementation, the tests passed again:

       

          def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
            buffer.put_int64((to_i * 1000) + (usec / 1000))
          end

       

      The failures are centered around Mongo date range aggregations constructed like so:

              {
                '$match' => {
                  'reporting_on' => { '$gte' => starts_at.utc, '$lte' => ends_at.utc },
                  'total_results' => total_results_query
                }
              }
       

      The starts_at and ends_at dates are coming from localized ActiveSupport::TimeWithZone objects. We convert them to UTC before running aggregation queries on them, since the aggregation pipeline does not automatically convert these objects to UTC before running the query like the rest of Mongoid.

      Since I can't reproduce this issue by checking the distance of a date range in 4.7.1 and 4.8.0, and since date range tests are not failing elsewhere, my hunch is that this probably has something to do with the relationship between BSON::Time objects and Mongo's aggregation pipeline.

            Assignee:
            oleg.pudeyev@mongodb.com Oleg Pudeyev (Inactive)
            Reporter:
            tscott@workarea.com Tom Scott
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: