Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-27745

Implement LogicalClock

    • Type: Icon: Task Task
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • 3.5.3
    • Affects Version/s: None
    • Component/s: Sharding
    • Labels:
      None
    • Fully Compatible
    • Sharding 2017-02-13

      LogicalClock class provides API to change the LogicalTime. Currently its done via global functions in global_timestamp where the equivalent of LogicalTime class is AtomicUInt64.

      The suggested LogicalClock API:

      class LogicalClock:
      public:
            void setClusterTime(const LogicalTime& newTime);
            const LogicalTime& getClusterTime() const;
           
           // increments clusterTime and return the result. this method should sync with the wall clock 
           LogicalTime addTicks(unsigned ticks);
      
          // increments clusterTime but returns the time before the increment therefor "reserving" ticks.
          // Needed for the batch writes oplog functionality. this method should sync with the wall clock  
          LogicalTime reserveTicks(unsigned ticks);
        
        private:
            mutable stdx::mutex _mutex; // unless there is a measurable performance degradation 
                                                           // serialize on mutex
            LogicalTime _clusterTime;
       };
      
      LogicalTime LogicalClock::reserveTicks(unsigned ticks) {
        
            const unsigned wallClockSecs = durationCount<Seconds>(
                getGlobalServiceContext()->getFastClockSource()->now().toDurationSinceEpoch());
          
            stdx::lock_guard<stdx::mutex> lock(_mutex);
            // Optimistic assumption that seconds did not change
            LogicalTime currentTime = _clusterTime;
           _clusterTime.addTicks(ticks);
        
            unsigned currentSecs = _clusterTime.asTimestamp().getSecs();
            // If the seconds need to be updated, try to do it. This can happen at most once per second.
            if (MONGO_unlikely(currentSecs < wallClockSecs)) {
                // First fix the seconds portion. 
               _clusterTime = LogicalTime(Timestamp(wallClockSecs, 1));
                currentTime = _clusterTime;
                _clusterTime.addTicks(ticks);
            }
        
            return currentTime;
        }
       
      

      The Implementation should decouple RateCheck into a separate class and depend on it.
      The task should include unit tests that will need mock for the wall clocks that will verify API

            Assignee:
            misha.tyulenev@mongodb.com Misha Tyulenev (Inactive)
            Reporter:
            misha.tyulenev@mongodb.com Misha Tyulenev (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: