Module: TjScaleRuby

Defined in:
lib/tj-scale.rb,
lib/tj_scale_ruby/version.rb,
lib/tj_scale_ruby/job_backends.rb,
lib/tj_scale_ruby/configuration.rb,
lib/tj_scale_ruby/job_backends/sidekiq.rb,
lib/tj_scale_ruby/models/tj_scale_ruby.rb,
lib/tj_scale_ruby/job_backends/delayed_job.rb,
lib/tj_scale_ruby/rack_queue_time_middleware.rb

Overview

Version module for TjScaleRuby gem

Defined Under Namespace

Modules: JobBackends Classes: Configuration, JobMonitor, RackQueueTimeMiddleware, Railtie

Constant Summary collapse

VERSION =
"1.0.0"

Class Method Summary collapse

Class Method Details

.clear_monitoring_memo!Object



91
92
93
# File 'lib/tj-scale.rb', line 91

def self.clear_monitoring_memo!
  remove_instance_variable(:@monitor_on_this_dyno) if defined?(@monitor_on_this_dyno)
end

.clear_web_queue_time_snapshot!Object



94
95
96
# File 'lib/tj_scale_ruby/configuration.rb', line 94

def clear_web_queue_time_snapshot!
  web_queue_mutex.synchronize { @web_queue_time_ms = nil }
end

.clear_web_traffic_stats!Object



123
124
125
126
127
128
# File 'lib/tj_scale_ruby/configuration.rb', line 123

def clear_web_traffic_stats!
  web_traffic_mutex.synchronize do
    @web_request_count = 0
    @web_response_time_sum_ms = 0
  end
end

.configurationObject



65
66
67
# File 'lib/tj_scale_ruby/configuration.rb', line 65

def configuration
  @configuration ||= Configuration.new
end

.configuration=(config) ⇒ Object



69
70
71
# File 'lib/tj_scale_ruby/configuration.rb', line 69

def configuration=(config)
  @configuration = config
end

.flush_web_traffic_stats_for_payload!Hash

Returns :job_count requests since last flush; :response_time_ms average ms or nil.

Returns:

  • (Hash)

    :job_count requests since last flush; :response_time_ms average ms or nil



112
113
114
115
116
117
118
119
120
121
# File 'lib/tj_scale_ruby/configuration.rb', line 112

def flush_web_traffic_stats_for_payload!
  web_traffic_mutex.synchronize do
    c = @web_request_count || 0
    sum = @web_response_time_sum_ms || 0
    @web_request_count = 0
    @web_response_time_sum_ms = 0
    avg = c.positive? ? (sum.to_f / c).round : nil
    { job_count: c, response_time_ms: avg }
  end
end

.last_web_queue_time_msObject



90
91
92
# File 'lib/tj_scale_ruby/configuration.rb', line 90

def last_web_queue_time_ms
  web_queue_mutex.synchronize { @web_queue_time_ms }
end

.monitor_on_this_dyno?Boolean

True when this dyno should run the metrics loop (first of TJ_SCALE_MONITOR_PROCESS). Result is memoized; cleared by reset_configuration!.

Returns:

  • (Boolean)


74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/tj-scale.rb', line 74

def self.monitor_on_this_dyno?
  return @monitor_on_this_dyno if defined?(@monitor_on_this_dyno)

  dyno = ENV["DYNO"]
  @monitor_on_this_dyno = if dyno.nil? || dyno.empty?
    false
  else
    parts = dyno.split(".", 2)
    if parts.size != 2
      false
    else
      process, index = parts
      process == configuration.monitor_process && index.to_i == 1
    end
  end
end

.record_web_queue_time_ms!(ms) ⇒ Object

Latest web router queue time (ms) captured by RackQueueTimeMiddleware; thread-safe.



81
82
83
84
85
86
87
88
# File 'lib/tj_scale_ruby/configuration.rb', line 81

def record_web_queue_time_ms!(ms)
  v = Integer(ms)
  return if v.negative?

  web_queue_mutex.synchronize { @web_queue_time_ms = v }
rescue ArgumentError, TypeError
  nil
end

.record_web_request_finished!(duration_ms) ⇒ Object

Request volume + response time for web metrics (flushed each ingest tick).



99
100
101
102
103
104
105
106
107
108
109
# File 'lib/tj_scale_ruby/configuration.rb', line 99

def record_web_request_finished!(duration_ms)
  v = Integer(duration_ms)
  return if v.negative?

  web_traffic_mutex.synchronize do
    @web_request_count = (@web_request_count || 0) + 1
    @web_response_time_sum_ms = (@web_response_time_sum_ms || 0) + v
  end
rescue ArgumentError, TypeError
  nil
end

.reset_configuration!Object



73
74
75
76
77
78
# File 'lib/tj_scale_ruby/configuration.rb', line 73

def reset_configuration!
  @configuration = nil
  TjScaleRuby.clear_monitoring_memo!
  TjScaleRuby.clear_web_queue_time_snapshot!
  TjScaleRuby.clear_web_traffic_stats!
end

.start_monitoring_loop!Object

Starts a background thread on the designated first dyno (see #monitor_on_this_dyno?).



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/tj-scale.rb', line 55

def self.start_monitoring_loop!
  return unless monitor_on_this_dyno?

  interval = configuration.interval_seconds
  Thread.new do
    loop do
      begin
        JobMonitor.send_log
      rescue StandardError => e
        Rails.logger.error("TjScaleRuby: Error in monitoring loop: #{e.message}")
      end

      sleep(interval)
    end
  end
end

.web_queue_mutexObject



130
131
132
# File 'lib/tj_scale_ruby/configuration.rb', line 130

def web_queue_mutex
  @web_queue_mutex ||= Mutex.new
end

.web_traffic_mutexObject



135
136
137
# File 'lib/tj_scale_ruby/configuration.rb', line 135

def web_traffic_mutex
  @web_traffic_mutex ||= Mutex.new
end