Sha256: 1b1c0f680038595c10b3e8a740707c7f176d625d768c4eca8f5d3eccd6888db3

Contents?: true

Size: 1.92 KB

Versions: 8

Compression:

Stored size: 1.92 KB

Contents

require "skylight/util/logging"

module Skylight
  # @api private
  class GC
    METHODS   = %i[enable total_time].freeze
    TH_KEY    = :SK_GC_CURR_WINDOW
    MAX_COUNT = 1000
    MAX_TIME  = 30_000_000

    include Util::Logging

    attr_reader :config

    def initialize(config, profiler)
      @listeners = []
      @config    = config
      @lock      = Mutex.new
      @time      = 0

      if METHODS.all? { |m| profiler.respond_to?(m) }
        @profiler = profiler
        @time = @profiler.total_time
      else
        debug "disabling GC profiling"
      end
    end

    def enable
      @profiler&.enable
    end

    # Total time in microseconds for GC over entire process lifetime
    def total_time
      @profiler ? @profiler.total_time : nil
    end

    def track
      if @profiler
        win = Window.new(self)

        @lock.synchronize do
          __update
          @listeners << win

          # Cleanup any listeners that might have leaked
          @listeners.shift until @listeners[0].time < MAX_TIME

          if @listeners.length > MAX_COUNT
            @listeners.shift
          end
        end

        win
      else
        Window.new(nil)
      end
    end

    def release(win)
      @lock.synchronize do
        @listeners.delete(win)
      end
    end

    def update
      @lock.synchronize do
        __update
      end

      nil
    end

    private

      def __update
        time  = @profiler.total_time
        diff  = time - @time
        @time = time

        if diff > 0
          @listeners.each do |l|
            l.add(diff)
          end
        end
      end

      class Window
        attr_reader :time

        def initialize(global)
          @global = global
          @time   = 0
        end

        def update
          @global&.update
        end

        def add(time)
          @time += time
        end

        def release
          @global&.release(self)
        end
      end
  end
end

Version data entries

8 entries across 8 versions & 1 rubygems

Version Path
skylight-5.1.0.beta lib/skylight/gc.rb
skylight-5.0.1 lib/skylight/gc.rb
skylight-5.0.0 lib/skylight/gc.rb
skylight-5.0.0.beta5 lib/skylight/gc.rb
skylight-5.0.0.beta4 lib/skylight/gc.rb
skylight-5.0.0.beta3 lib/skylight/gc.rb
skylight-5.0.0.beta2 lib/skylight/gc.rb
skylight-5.0.0.beta lib/skylight/gc.rb