Class: Google::Ads::GoogleAds::CallerFilter Private

Inherits:
Object
  • Object
show all
Defined in:
lib/google/ads/google_ads/deprecation.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Portions of this implementation were copied from RSpec, under the MIT license: git.io/fjR7i

Constant Summary collapse

LIB_REGEX =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

/lib\/google\/ads\/google_ads/
GRPC_REGEX =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

/lib\/(grpc|gapic)/
STDLIB_REGEX =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

/lib\/ruby/
IGNORE_REGEX =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Regexp.union(
  LIB_REGEX,
  STDLIB_REGEX,
  GRPC_REGEX,
  "rubygems/core_ext/kernel_require.rb"
)

Class Method Summary collapse

Class Method Details

.first_non_google_ads_lineObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method finds the first line from the current stack trace that doesn’t originate from lib/google/ads/google_ads. It does this by running backwards through the current stack trace in chunks. The reason for this is that pulling the entire stack trace is O(n) on the depth of the stack (which is in practice very expensive in Rails applications, because rails ads a lot stack frames on to every request).

The chunking algorithm works by skipping a certain number of frames, and then pulling a static number, consider a stack trace as folows, where frame 17 is the one we’re interested in, and we’re actually, thousands of frames deep.

*

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

the first iteration of this will skip frames 0-2 and pull frames 3-7 (skip_frames = 3, increment = 5, 3 + 5 -1 = 7). Skipping is free, and pulling chunks is O(n) on the size of the chunk.

*

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

^_______^

if the relevant stack frame isn’t found, skip is incremented, to point at frame 8, and the increment is doubled, doubling the size of the search window, causing it to point at frame 17

*

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

^________________________^

here, we’ve performed 15 lookup operations to find the item we’re looking for, instead of 1000. The reason we use this chunk and doubling strategy is that pulling stack frames has some fixed overhead, and so in practice, doing a linear scan from frame 0 to the one we’re interested in is also slower than this methodology, even though the doubling strategy may result in strictly more lookups thn necessary.



90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/google/ads/google_ads/deprecation.rb', line 90

def self.first_non_google_ads_line
  skip_frames = 3
  increment = 5
  loop do
    stack = caller_locations(skip_frames, increment)
    raise "No non-lib lines in stack" unless stack

    line = stack.find { |l| l.path !~ IGNORE_REGEX }
    return line.to_s if line

    skip_frames += increment
    increment   *= 2 # The choice of two here is arbitrary.
  end
end