Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDouglas Barbosa Alexandre <dbalexandre@gmail.com>2016-04-11 16:34:49 +0300
committerDouglas Barbosa Alexandre <dbalexandre@gmail.com>2016-04-11 16:34:49 +0300
commit9a44d6977ad27a443538b2b6c34b3fdd722e9bd6 (patch)
tree487aa6ad827b903aa2c78542d9252d056d9e1238 /lib
parent73fdd4b83d76998fef9770dbeaf05981d4500b8c (diff)
parent15cbbd09fbd05cfd2447dfb43d66d7a96a708f82 (diff)
Merge branch 'master' into decouple-member-notification
Diffstat (limited to 'lib')
-rw-r--r--lib/gitlab/exclusive_lease.rb4
-rw-r--r--lib/gitlab/metrics.rb34
-rw-r--r--lib/gitlab/metrics/subscribers/rails_cache.rb39
-rw-r--r--lib/gitlab/metrics/system.rb11
-rw-r--r--lib/gitlab/redis.rb48
-rw-r--r--lib/gitlab/redis_config.rb30
-rw-r--r--lib/tasks/cache.rake25
7 files changed, 138 insertions, 53 deletions
diff --git a/lib/gitlab/exclusive_lease.rb b/lib/gitlab/exclusive_lease.rb
index c73eca832d7..c2260a5f7ac 100644
--- a/lib/gitlab/exclusive_lease.rb
+++ b/lib/gitlab/exclusive_lease.rb
@@ -43,7 +43,9 @@ module Gitlab
# false if the lease is already taken.
def try_obtain
# Performing a single SET is atomic
- !!redis.set(redis_key, '1', nx: true, ex: @timeout)
+ Gitlab::Redis.with do |redis|
+ !!redis.set(redis_key, '1', nx: true, ex: @timeout)
+ end
end
# No #cancel method. See comments above!
diff --git a/lib/gitlab/metrics.rb b/lib/gitlab/metrics.rb
index 4a3f47b5a95..2a0a5629be5 100644
--- a/lib/gitlab/metrics.rb
+++ b/lib/gitlab/metrics.rb
@@ -74,24 +74,32 @@ module Gitlab
#
# Example:
#
- # Gitlab::Metrics.measure(:find_by_username_timings) do
+ # Gitlab::Metrics.measure(:find_by_username_duration) do
# User.find_by_username(some_username)
# end
#
- # series - The name of the series to store the data in.
- # values - A Hash containing extra values to add to the metric.
- # tags - A Hash containing extra tags to add to the metric.
+ # name - The name of the field to store the execution time in.
#
# Returns the value yielded by the supplied block.
- def self.measure(series, values = {}, tags = {})
- return yield unless Transaction.current
+ def self.measure(name)
+ trans = current_transaction
+
+ return yield unless trans
+
+ real_start = Time.now.to_f
+ cpu_start = System.cpu_time
- start = Time.now.to_f
retval = yield
- duration = (Time.now.to_f - start) * 1000.0
- values = values.merge(duration: duration)
- Transaction.current.add_metric(series, values, tags)
+ cpu_stop = System.cpu_time
+ real_stop = Time.now.to_f
+
+ real_time = (real_stop - real_start) * 1000.0
+ cpu_time = cpu_stop - cpu_start
+
+ trans.increment("#{name}_real_time", real_time)
+ trans.increment("#{name}_cpu_time", cpu_time)
+ trans.increment("#{name}_call_count", 1)
retval
end
@@ -107,5 +115,11 @@ module Gitlab
new(udp: { host: host, port: port })
end
end
+
+ private
+
+ def self.current_transaction
+ Transaction.current
+ end
end
end
diff --git a/lib/gitlab/metrics/subscribers/rails_cache.rb b/lib/gitlab/metrics/subscribers/rails_cache.rb
new file mode 100644
index 00000000000..49e5f86e6e6
--- /dev/null
+++ b/lib/gitlab/metrics/subscribers/rails_cache.rb
@@ -0,0 +1,39 @@
+module Gitlab
+ module Metrics
+ module Subscribers
+ # Class for tracking the total time spent in Rails cache calls
+ class RailsCache < ActiveSupport::Subscriber
+ attach_to :active_support
+
+ def cache_read(event)
+ increment(:cache_read_duration, event.duration)
+ end
+
+ def cache_write(event)
+ increment(:cache_write_duration, event.duration)
+ end
+
+ def cache_delete(event)
+ increment(:cache_delete_duration, event.duration)
+ end
+
+ def cache_exist?(event)
+ increment(:cache_exists_duration, event.duration)
+ end
+
+ def increment(key, duration)
+ return unless current_transaction
+
+ current_transaction.increment(:cache_duration, duration)
+ current_transaction.increment(key, duration)
+ end
+
+ private
+
+ def current_transaction
+ Transaction.current
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/metrics/system.rb b/lib/gitlab/metrics/system.rb
index 83371265278..a7d183b2f94 100644
--- a/lib/gitlab/metrics/system.rb
+++ b/lib/gitlab/metrics/system.rb
@@ -30,6 +30,17 @@ module Gitlab
0
end
end
+
+ # THREAD_CPUTIME is not supported on OS X
+ if Process.const_defined?(:CLOCK_THREAD_CPUTIME_ID)
+ def self.cpu_time
+ Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :millisecond)
+ end
+ else
+ def self.cpu_time
+ Process.clock_gettime(Process::CLOCK_PROCESS_CPUTIME_ID, :millisecond)
+ end
+ end
end
end
end
diff --git a/lib/gitlab/redis.rb b/lib/gitlab/redis.rb
new file mode 100644
index 00000000000..319447669dc
--- /dev/null
+++ b/lib/gitlab/redis.rb
@@ -0,0 +1,48 @@
+module Gitlab
+ class Redis
+ CACHE_NAMESPACE = 'cache:gitlab'
+
+ attr_reader :url
+
+ # To be thread-safe we must be careful when writing the class instance
+ # variables @url and @pool. Because @pool depends on @url we need two
+ # mutexes to prevent deadlock.
+ URL_MUTEX = Mutex.new
+ POOL_MUTEX = Mutex.new
+ private_constant :URL_MUTEX, :POOL_MUTEX
+
+ def self.url
+ @url || URL_MUTEX.synchronize { @url = new.url }
+ end
+
+ def self.with
+ if @pool.nil?
+ POOL_MUTEX.synchronize do
+ @pool = ConnectionPool.new { ::Redis.new(url: url) }
+ end
+ end
+ @pool.with { |redis| yield redis }
+ end
+
+ def self.redis_store_options
+ url = new.url
+ redis_config_hash = ::Redis::Store::Factory.extract_host_options_from_uri(url)
+ # Redis::Store does not handle Unix sockets well, so let's do it for them
+ redis_uri = URI.parse(url)
+ if redis_uri.scheme == 'unix'
+ redis_config_hash[:path] = redis_uri.path
+ end
+ redis_config_hash
+ end
+
+ def initialize(rails_env=nil)
+ rails_env ||= Rails.env
+ config_file = File.expand_path('../../../config/resque.yml', __FILE__)
+
+ @url = "redis://localhost:6379"
+ if File.exists?(config_file)
+ @url =YAML.load_file(config_file)[rails_env]
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/redis_config.rb b/lib/gitlab/redis_config.rb
deleted file mode 100644
index 4949c6db539..00000000000
--- a/lib/gitlab/redis_config.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-module Gitlab
- class RedisConfig
- attr_reader :url
-
- def self.url
- new.url
- end
-
- def self.redis_store_options
- url = new.url
- redis_config_hash = Redis::Store::Factory.extract_host_options_from_uri(url)
- # Redis::Store does not handle Unix sockets well, so let's do it for them
- redis_uri = URI.parse(url)
- if redis_uri.scheme == 'unix'
- redis_config_hash[:path] = redis_uri.path
- end
- redis_config_hash
- end
-
- def initialize(rails_env=nil)
- rails_env ||= Rails.env
- config_file = File.expand_path('../../../config/resque.yml', __FILE__)
-
- @url = "redis://localhost:6379"
- if File.exists?(config_file)
- @url =YAML.load_file(config_file)[rails_env]
- end
- end
- end
-end
diff --git a/lib/tasks/cache.rake b/lib/tasks/cache.rake
index 51e746ef923..2214f855200 100644
--- a/lib/tasks/cache.rake
+++ b/lib/tasks/cache.rake
@@ -4,18 +4,19 @@ namespace :cache do
desc "GitLab | Clear redis cache"
task :clear => :environment do
- redis = Redis.new(url: Gitlab::RedisConfig.url)
- cursor = REDIS_SCAN_START_STOP
- loop do
- cursor, keys = redis.scan(
- cursor,
- match: "#{Gitlab::REDIS_CACHE_NAMESPACE}*",
- count: CLEAR_BATCH_SIZE
- )
-
- redis.del(*keys) if keys.any?
-
- break if cursor == REDIS_SCAN_START_STOP
+ Gitlab::Redis.with do |redis|
+ cursor = REDIS_SCAN_START_STOP
+ loop do
+ cursor, keys = redis.scan(
+ cursor,
+ match: "#{Gitlab::Redis::CACHE_NAMESPACE}*",
+ count: CLEAR_BATCH_SIZE
+ )
+
+ redis.del(*keys) if keys.any?
+
+ break if cursor == REDIS_SCAN_START_STOP
+ end
end
end
end