diff options
author | Douglas Barbosa Alexandre <dbalexandre@gmail.com> | 2016-01-26 00:04:09 +0000 |
---|---|---|
committer | Robert Speicher <rspeicher@gmail.com> | 2016-01-25 16:10:20 -0800 |
commit | 6881ba0e796fe22dd1d47bd1a7d42e532f18077a (patch) | |
tree | 654a99b8493c544fff34f6a52d2d6fa2b532b5e9 | |
parent | 65d85a4403f6e5899f793acb53c64d7ad5ba7fdd (diff) | |
download | gitlab-ce-6881ba0e796fe22dd1d47bd1a7d42e532f18077a.tar.gz |
Merge branch 'instrumentation-signature' into 'master'
Correct arity for instrumented methods w/o args
This should fix the problem of imports not working. See https://gitlab.com/gitlab-org/gitlab-ce/issues/12450#note_3380730 for the details/context of these changes.
See merge request !2602
-rw-r--r-- | lib/gitlab/metrics/instrumentation.rb | 22 | ||||
-rw-r--r-- | spec/lib/gitlab/metrics/instrumentation_spec.rb | 10 |
2 files changed, 29 insertions, 3 deletions
diff --git a/lib/gitlab/metrics/instrumentation.rb b/lib/gitlab/metrics/instrumentation.rb index d9fce2e6758..face1921d2e 100644 --- a/lib/gitlab/metrics/instrumentation.rb +++ b/lib/gitlab/metrics/instrumentation.rb @@ -106,20 +106,36 @@ module Gitlab if type == :instance target = mod label = "#{mod.name}##{name}" + method = mod.instance_method(name) else target = mod.singleton_class label = "#{mod.name}.#{name}" + method = mod.method(name) + end + + # Some code out there (e.g. the "state_machine" Gem) checks the arity of + # a method to make sure it only passes arguments when the method expects + # any. If we were to always overwrite a method to take an `*args` + # signature this would break things. As a result we'll make sure the + # generated method _only_ accepts regular arguments if the underlying + # method also accepts them. + if method.arity == 0 + args_signature = '&block' + else + args_signature = '*args, &block' end + send_signature = "__send__(#{alias_name.inspect}, #{args_signature})" + target.class_eval <<-EOF, __FILE__, __LINE__ + 1 alias_method #{alias_name.inspect}, #{name.inspect} - def #{name}(*args, &block) + def #{name}(#{args_signature}) trans = Gitlab::Metrics::Instrumentation.transaction if trans start = Time.now - retval = __send__(#{alias_name.inspect}, *args, &block) + retval = #{send_signature} duration = (Time.now - start) * 1000.0 if duration >= Gitlab::Metrics.method_call_threshold @@ -132,7 +148,7 @@ module Gitlab retval else - __send__(#{alias_name.inspect}, *args, &block) + #{send_signature} end end EOF diff --git a/spec/lib/gitlab/metrics/instrumentation_spec.rb b/spec/lib/gitlab/metrics/instrumentation_spec.rb index 2a37cd40dde..ad4290c43bb 100644 --- a/spec/lib/gitlab/metrics/instrumentation_spec.rb +++ b/spec/lib/gitlab/metrics/instrumentation_spec.rb @@ -66,6 +66,16 @@ describe Gitlab::Metrics::Instrumentation do @dummy.foo end + + it 'generates a method with the correct arity when using methods without arguments' do + dummy = Class.new do + def self.test; end + end + + described_class.instrument_method(dummy, :test) + + expect(dummy.method(:test).arity).to eq(0) + end end describe 'with metrics disabled' do |