skylight-core 4.0.0.alpha4 → 4.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5b333f6d3704521099216e030773e068bbae7fb08cdea202b8ffc81e76a0beed
4
- data.tar.gz: 00042ab9ca7c24ccba1ea0ebebcbfb664aa78755cfc9d6ae6595f2f7e5754bd4
3
+ metadata.gz: ab9eed2e498ca4b55dfed12501b36fdea71433e0505a2c34733a0d025b03bbdd
4
+ data.tar.gz: c5a4eed17eb02f2beb8e0b54e90196429467676a9b79dbff10ecd24d0cd9c31d
5
5
  SHA512:
6
- metadata.gz: 38a125f7978eb1c05a848a06edaf10ffea2b16227ea474ea0e9a069633ed40029baf8667e569a9664621a486e0bea053011609c9703d634f20ca04489d9aae46
7
- data.tar.gz: c53a44d21608de2a245a8b36ef8d7d4b02870723c88dde340d036473803002f2bef202354cafe3e5b040988adc083dceebf4e575508add93d068945dd13f1fd5
6
+ metadata.gz: 823f266c1a844a4e8424569b34f35afb9b5998c2688b66e299bbc4ad16c335aceffa17d24ed0c38243d89f7b8b16b202f65fdb8d416dc13a830e3505848b86a2
7
+ data.tar.gz: 6c134666859922615c8083298fd42d7d7b04bbb6d2845ab08071daadb65fcc19aa471361cc197b84ddecb708694b3bebb3d8e35f9f825985348c5eacf4809afe
@@ -11,13 +11,14 @@ module Skylight::Core
11
11
  adapter_name = normalize_adapter_name(payload[:adapter])
12
12
  desc = "{ adapter: '#{adapter_name}', queue: '#{payload[:job].queue_name}' }"
13
13
 
14
- maybe_set_endpoint(trace, title)
14
+ maybe_set_endpoint(trace, payload)
15
15
 
16
16
  [CAT, title, desc]
17
17
  end
18
18
 
19
19
  def normalize_after(trace, _span, _name, payload)
20
- return unless config.enable_segments?
20
+ return unless config.enable_segments? && assign_endpoint?(trace, payload)
21
+
21
22
  trace.segment = payload[:job].queue_name
22
23
  end
23
24
 
@@ -30,14 +31,29 @@ module Skylight::Core
30
31
  "active_job"
31
32
  end
32
33
 
33
- def maybe_set_endpoint(trace, string)
34
- trace.endpoint ||= string
34
+ def maybe_set_endpoint(trace, payload)
35
+ if assign_endpoint?(trace, payload)
36
+ trace.endpoint = normalize_title(payload[:job])
37
+ end
38
+ end
39
+
40
+ def assign_endpoint?(trace, payload)
41
+ # Always assign the endpoint if it has not yet been assigned by the ActiveJob probe.
42
+ return true unless trace.endpoint
43
+ return unless defined?(Skylight::Core::Probes::ActiveJob::Probe::TITLE)
35
44
 
36
45
  # If a job is called using #perform_now inside a controller action
37
46
  # or within another job's #perform method, we do not want this to
38
47
  # overwrite the existing endpoint name (unless it is the default from ActiveJob).
39
- return unless trace.endpoint == Skylight::Core::Probes::ActiveJob::Probe::TITLE
40
- trace.endpoint = string
48
+ #
49
+ # If the current endpoint name matches this payload, return true to allow the
50
+ # segment to be assigned by normalize_after.
51
+ trace.endpoint == Skylight::Core::Probes::ActiveJob::Probe::TITLE ||
52
+ trace.endpoint == normalize_title(payload[:job])
53
+ end
54
+
55
+ def normalize_title(job_instance)
56
+ job_instance.class.to_s
41
57
  end
42
58
  end
43
59
  end
@@ -6,12 +6,20 @@ module Skylight::Core
6
6
  ::ActionView::TemplateRenderer.class_eval do
7
7
  alias_method :render_with_layout_without_sk, :render_with_layout
8
8
 
9
- def render_with_layout(path, locals, *args, &block) #:nodoc:
9
+ def render_with_layout(*args, &block) #:nodoc:
10
+ path, locals = case args.length
11
+ when 2
12
+ args
13
+ when 3
14
+ # Rails > 6.0.0.beta1 prepends an additional `view` argument
15
+ args.last(2)
16
+ end
17
+
10
18
  layout = nil
11
19
 
12
20
  if path
13
21
  layout =
14
- if ::ActionView.gem_version >= Gem::Version.new("5.x")
22
+ if ::ActionView::VERSION::MAJOR >= 5
15
23
  find_layout(path, locals.keys, [formats.first])
16
24
  else
17
25
  find_layout(path, locals.keys)
@@ -20,10 +28,10 @@ module Skylight::Core
20
28
 
21
29
  if layout
22
30
  instrument(:template, identifier: layout.identifier) do
23
- render_with_layout_without_sk(path, locals, *args, &block)
31
+ render_with_layout_without_sk(*args, &block)
24
32
  end
25
33
  else
26
- render_with_layout_without_sk(path, locals, *args, &block)
34
+ render_with_layout_without_sk(*args, &block)
27
35
  end
28
36
  end
29
37
  end
@@ -1,5 +1,5 @@
1
1
  module Skylight
2
2
  module Core
3
- VERSION = "4.0.0-alpha4".freeze
3
+ VERSION = "4.0.0-beta".freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skylight-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0.alpha4
4
+ version: 4.0.0.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tilde, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-16 00:00:00.000000000 Z
11
+ date: 2019-02-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -244,11 +244,6 @@ files:
244
244
  - lib/skylight/core/util/logging.rb
245
245
  - lib/skylight/core/util/platform.rb
246
246
  - lib/skylight/core/util/proxy.rb
247
- - lib/skylight/core/vendor/active_support/notifications.rb
248
- - lib/skylight/core/vendor/active_support/per_thread_registry.rb
249
- - lib/skylight/core/vendor/thread_safe.rb
250
- - lib/skylight/core/vendor/thread_safe/non_concurrent_cache_backend.rb
251
- - lib/skylight/core/vendor/thread_safe/synchronized_cache_backend.rb
252
247
  - lib/skylight/core/version.rb
253
248
  - lib/skylight/core/vm/gc.rb
254
249
  homepage: https://www.skylight.io
@@ -1,207 +0,0 @@
1
- require 'skylight/core/vendor/active_support/notifications/instrumenter'
2
- require 'skylight/core/vendor/active_support/notifications/fanout'
3
- require 'skylight/core/vendor/active_support/per_thread_registry'
4
-
5
- module ActiveSupport
6
- # = Notifications
7
- #
8
- # <tt>ActiveSupport::Notifications</tt> provides an instrumentation API for
9
- # Ruby.
10
- #
11
- # == Instrumenters
12
- #
13
- # To instrument an event you just need to do:
14
- #
15
- # ActiveSupport::Notifications.instrument('render', extra: :information) do
16
- # render text: 'Foo'
17
- # end
18
- #
19
- # That executes the block first and notifies all subscribers once done.
20
- #
21
- # In the example above +render+ is the name of the event, and the rest is called
22
- # the _payload_. The payload is a mechanism that allows instrumenters to pass
23
- # extra information to subscribers. Payloads consist of a hash whose contents
24
- # are arbitrary and generally depend on the event.
25
- #
26
- # == Subscribers
27
- #
28
- # You can consume those events and the information they provide by registering
29
- # a subscriber.
30
- #
31
- # ActiveSupport::Notifications.subscribe('render') do |name, start, finish, id, payload|
32
- # name # => String, name of the event (such as 'render' from above)
33
- # start # => Time, when the instrumented block started execution
34
- # finish # => Time, when the instrumented block ended execution
35
- # id # => String, unique ID for this notification
36
- # payload # => Hash, the payload
37
- # end
38
- #
39
- # For instance, let's store all "render" events in an array:
40
- #
41
- # events = []
42
- #
43
- # ActiveSupport::Notifications.subscribe('render') do |*args|
44
- # events << ActiveSupport::Notifications::Event.new(*args)
45
- # end
46
- #
47
- # That code returns right away, you are just subscribing to "render" events.
48
- # The block is saved and will be called whenever someone instruments "render":
49
- #
50
- # ActiveSupport::Notifications.instrument('render', extra: :information) do
51
- # render text: 'Foo'
52
- # end
53
- #
54
- # event = events.first
55
- # event.name # => "render"
56
- # event.duration # => 10 (in milliseconds)
57
- # event.payload # => { extra: :information }
58
- #
59
- # The block in the <tt>subscribe</tt> call gets the name of the event, start
60
- # timestamp, end timestamp, a string with a unique identifier for that event
61
- # (something like "535801666f04d0298cd6"), and a hash with the payload, in
62
- # that order.
63
- #
64
- # If an exception happens during that particular instrumentation the payload will
65
- # have a key <tt>:exception</tt> with an array of two elements as value: a string with
66
- # the name of the exception class, and the exception message.
67
- #
68
- # As the previous example depicts, the class <tt>ActiveSupport::Notifications::Event</tt>
69
- # is able to take the arguments as they come and provide an object-oriented
70
- # interface to that data.
71
- #
72
- # It is also possible to pass an object as the second parameter passed to the
73
- # <tt>subscribe</tt> method instead of a block:
74
- #
75
- # module ActionController
76
- # class PageRequest
77
- # def call(name, started, finished, unique_id, payload)
78
- # Rails.logger.debug ['notification:', name, started, finished, unique_id, payload].join(' ')
79
- # end
80
- # end
81
- # end
82
- #
83
- # ActiveSupport::Notifications.subscribe('process_action.action_controller', ActionController::PageRequest.new)
84
- #
85
- # resulting in the following output within the logs including a hash with the payload:
86
- #
87
- # notification: process_action.action_controller 2012-04-13 01:08:35 +0300 2012-04-13 01:08:35 +0300 af358ed7fab884532ec7 {
88
- # controller: "Devise::SessionsController",
89
- # action: "new",
90
- # params: {"action"=>"new", "controller"=>"devise/sessions"},
91
- # format: :html,
92
- # method: "GET",
93
- # path: "/login/sign_in",
94
- # status: 200,
95
- # view_runtime: 279.3080806732178,
96
- # db_runtime: 40.053
97
- # }
98
- #
99
- # You can also subscribe to all events whose name matches a certain regexp:
100
- #
101
- # ActiveSupport::Notifications.subscribe(/render/) do |*args|
102
- # ...
103
- # end
104
- #
105
- # and even pass no argument to <tt>subscribe</tt>, in which case you are subscribing
106
- # to all events.
107
- #
108
- # == Temporary Subscriptions
109
- #
110
- # Sometimes you do not want to subscribe to an event for the entire life of
111
- # the application. There are two ways to unsubscribe.
112
- #
113
- # WARNING: The instrumentation framework is designed for long-running subscribers,
114
- # use this feature sparingly because it wipes some internal caches and that has
115
- # a negative impact on performance.
116
- #
117
- # === Subscribe While a Block Runs
118
- #
119
- # You can subscribe to some event temporarily while some block runs. For
120
- # example, in
121
- #
122
- # callback = lambda {|*args| ... }
123
- # ActiveSupport::Notifications.subscribed(callback, "sql.active_record") do
124
- # ...
125
- # end
126
- #
127
- # the callback will be called for all "sql.active_record" events instrumented
128
- # during the execution of the block. The callback is unsubscribed automatically
129
- # after that.
130
- #
131
- # === Manual Unsubscription
132
- #
133
- # The +subscribe+ method returns a subscriber object:
134
- #
135
- # subscriber = ActiveSupport::Notifications.subscribe("render") do |*args|
136
- # ...
137
- # end
138
- #
139
- # To prevent that block from being called anymore, just unsubscribe passing
140
- # that reference:
141
- #
142
- # ActiveSupport::Notifications.unsubscribe(subscriber)
143
- #
144
- # == Default Queue
145
- #
146
- # Notifications ships with a queue implementation that consumes and publish events
147
- # to log subscribers in a thread. You can use any queue implementation you want.
148
- #
149
- module Notifications
150
- class << self
151
- attr_accessor :notifier
152
-
153
- def publish(name, *args)
154
- notifier.publish(name, *args)
155
- end
156
-
157
- def instrument(name, payload = {})
158
- if notifier.listening?(name)
159
- instrumenter.instrument(name, payload) { yield payload if block_given? }
160
- else
161
- yield payload if block_given?
162
- end
163
- end
164
-
165
- def subscribe(*args, &block)
166
- notifier.subscribe(*args, &block)
167
- end
168
-
169
- def subscribed(callback, *args, &block)
170
- subscriber = subscribe(*args, &callback)
171
- yield
172
- ensure
173
- unsubscribe(subscriber)
174
- end
175
-
176
- def unsubscribe(args)
177
- notifier.unsubscribe(args)
178
- end
179
-
180
- def instrumenter
181
- InstrumentationRegistry.instrumenter_for(notifier)
182
- end
183
- end
184
-
185
- # This class is a registry which holds all of the +Instrumenter+ objects
186
- # in a particular thread local. To access the +Instrumenter+ object for a
187
- # particular +notifier+, you can call the following method:
188
- #
189
- # InstrumentationRegistry.instrumenter_for(notifier)
190
- #
191
- # The instrumenters for multiple notifiers are held in a single instance of
192
- # this class.
193
- class InstrumentationRegistry # :nodoc:
194
- extend ActiveSupport::PerThreadRegistry
195
-
196
- def initialize
197
- @registry = {}
198
- end
199
-
200
- def instrumenter_for(notifier)
201
- @registry[notifier] ||= Instrumenter.new(notifier)
202
- end
203
- end
204
-
205
- self.notifier = Fanout.new
206
- end
207
- end
@@ -1,52 +0,0 @@
1
- module ActiveSupport
2
- # This module is used to encapsulate access to thread local variables.
3
- #
4
- # Instead of polluting the thread locals namespace:
5
- #
6
- # Thread.current[:connection_handler]
7
- #
8
- # you define a class that extends this module:
9
- #
10
- # module ActiveRecord
11
- # class RuntimeRegistry
12
- # extend ActiveSupport::PerThreadRegistry
13
- #
14
- # attr_accessor :connection_handler
15
- # end
16
- # end
17
- #
18
- # and invoke the declared instance accessors as class methods. So
19
- #
20
- # ActiveRecord::RuntimeRegistry.connection_handler = connection_handler
21
- #
22
- # sets a connection handler local to the current thread, and
23
- #
24
- # ActiveRecord::RuntimeRegistry.connection_handler
25
- #
26
- # returns a connection handler local to the current thread.
27
- #
28
- # This feature is accomplished by instantiating the class and storing the
29
- # instance as a thread local keyed by the class name. In the example above
30
- # a key "ActiveRecord::RuntimeRegistry" is stored in <tt>Thread.current</tt>.
31
- # The class methods proxy to said thread local instance.
32
- #
33
- # If the class has an initializer, it must accept no arguments.
34
- module PerThreadRegistry
35
- protected
36
-
37
- def method_missing(name, *args, &block) # :nodoc:
38
- # Caches the method definition as a singleton method of the receiver.
39
- define_singleton_method(name) do |*a, &b|
40
- per_thread_registry_instance.public_send(name, *a, &b)
41
- end
42
-
43
- send(name, *args, &block)
44
- end
45
-
46
- private
47
-
48
- def per_thread_registry_instance
49
- Thread.current[name] ||= new
50
- end
51
- end
52
- end
@@ -1,133 +0,0 @@
1
- module ThreadSafe
2
- class NonConcurrentCacheBackend
3
- # WARNING: all public methods of the class must operate on the @backend directly without calling each other. This is important
4
- # because of the SynchronizedCacheBackend which uses a non-reentrant mutex for perfomance reasons.
5
- def initialize(options = nil)
6
- @backend = {}
7
- end
8
-
9
- def [](key)
10
- @backend[key]
11
- end
12
-
13
- def []=(key, value)
14
- @backend[key] = value
15
- end
16
-
17
- def compute_if_absent(key)
18
- if NULL != (stored_value = @backend.fetch(key, NULL))
19
- stored_value
20
- else
21
- @backend[key] = yield
22
- end
23
- end
24
-
25
- def replace_pair(key, old_value, new_value)
26
- if pair?(key, old_value)
27
- @backend[key] = new_value
28
- true
29
- else
30
- false
31
- end
32
- end
33
-
34
- def replace_if_exists(key, new_value)
35
- if NULL != (stored_value = @backend.fetch(key, NULL))
36
- @backend[key] = new_value
37
- stored_value
38
- end
39
- end
40
-
41
- def compute_if_present(key)
42
- if NULL != (stored_value = @backend.fetch(key, NULL))
43
- store_computed_value(key, yield(stored_value))
44
- end
45
- end
46
-
47
- def compute(key)
48
- store_computed_value(key, yield(@backend[key]))
49
- end
50
-
51
- def merge_pair(key, value)
52
- if NULL == (stored_value = @backend.fetch(key, NULL))
53
- @backend[key] = value
54
- else
55
- store_computed_value(key, yield(stored_value))
56
- end
57
- end
58
-
59
- def get_and_set(key, value)
60
- stored_value = @backend[key]
61
- @backend[key] = value
62
- stored_value
63
- end
64
-
65
- def key?(key)
66
- @backend.key?(key)
67
- end
68
-
69
- def value?(value)
70
- @backend.value?(value)
71
- end
72
-
73
- def delete(key)
74
- @backend.delete(key)
75
- end
76
-
77
- def delete_pair(key, value)
78
- if pair?(key, value)
79
- @backend.delete(key)
80
- true
81
- else
82
- false
83
- end
84
- end
85
-
86
- def clear
87
- @backend.clear
88
- self
89
- end
90
-
91
- def each_pair
92
- dupped_backend.each_pair do |k, v|
93
- yield k, v
94
- end
95
- self
96
- end
97
-
98
- def size
99
- @backend.size
100
- end
101
-
102
- def get_or_default(key, default_value)
103
- @backend.fetch(key, default_value)
104
- end
105
-
106
- alias_method :_get, :[]
107
- alias_method :_set, :[]=
108
- private :_get, :_set
109
- private
110
- def initialize_copy(other)
111
- super
112
- @backend = {}
113
- self
114
- end
115
-
116
- def dupped_backend
117
- @backend.dup
118
- end
119
-
120
- def pair?(key, expected_value)
121
- NULL != (stored_value = @backend.fetch(key, NULL)) && expected_value.equal?(stored_value)
122
- end
123
-
124
- def store_computed_value(key, new_value)
125
- if new_value.nil?
126
- @backend.delete(key)
127
- nil
128
- else
129
- @backend[key] = new_value
130
- end
131
- end
132
- end
133
- end
@@ -1,76 +0,0 @@
1
- module ThreadSafe
2
- class SynchronizedCacheBackend < NonConcurrentCacheBackend
3
- require 'mutex_m'
4
- include Mutex_m
5
- # WARNING: Mutex_m is a non-reentrant lock, so the synchronized methods are not allowed to call each other.
6
-
7
- def [](key)
8
- synchronize { super }
9
- end
10
-
11
- def []=(key, value)
12
- synchronize { super }
13
- end
14
-
15
- def compute_if_absent(key)
16
- synchronize { super }
17
- end
18
-
19
- def compute_if_present(key)
20
- synchronize { super }
21
- end
22
-
23
- def compute(key)
24
- synchronize { super }
25
- end
26
-
27
- def merge_pair(key, value)
28
- synchronize { super }
29
- end
30
-
31
- def replace_pair(key, old_value, new_value)
32
- synchronize { super }
33
- end
34
-
35
- def replace_if_exists(key, new_value)
36
- synchronize { super }
37
- end
38
-
39
- def get_and_set(key, value)
40
- synchronize { super }
41
- end
42
-
43
- def key?(key)
44
- synchronize { super }
45
- end
46
-
47
- def value?(value)
48
- synchronize { super }
49
- end
50
-
51
- def delete(key)
52
- synchronize { super }
53
- end
54
-
55
- def delete_pair(key, value)
56
- synchronize { super }
57
- end
58
-
59
- def clear
60
- synchronize { super }
61
- end
62
-
63
- def size
64
- synchronize { super }
65
- end
66
-
67
- def get_or_default(key, default_value)
68
- synchronize { super }
69
- end
70
-
71
- private
72
- def dupped_backend
73
- synchronize { super }
74
- end
75
- end
76
- end
@@ -1,126 +0,0 @@
1
- require 'thread'
2
-
3
- module ThreadSafe
4
- autoload :NonConcurrentCacheBackend, 'skylight/core/vendor/thread_safe/non_concurrent_cache_backend'
5
- autoload :SynchronizedCacheBackend, 'skylight/core/vendor/thread_safe/synchronized_cache_backend'
6
-
7
- ConcurrentCacheBackend = SynchronizedCacheBackend
8
-
9
- class Cache < ConcurrentCacheBackend
10
- KEY_ERROR = defined?(KeyError) ? KeyError : IndexError # there is no KeyError in 1.8 mode
11
-
12
- def initialize(options = nil, &block)
13
- if options.kind_of?(::Hash)
14
- validate_options_hash!(options)
15
- else
16
- options = nil
17
- end
18
-
19
- super(options)
20
- @default_proc = block
21
- end
22
-
23
- def [](key)
24
- if value = super
25
- value
26
- elsif @default_proc && !key?(key)
27
- @default_proc.call(self, key)
28
- else
29
- value
30
- end
31
- end
32
-
33
- def fetch(key, default_value = NULL)
34
- if NULL != (value = get_or_default(key, NULL))
35
- value
36
- elsif block_given?
37
- yield key
38
- elsif NULL != default_value
39
- default_value
40
- else
41
- raise KEY_ERROR, 'key not found'
42
- end
43
- end
44
-
45
- def put_if_absent(key, value)
46
- computed = false
47
- result = compute_if_absent(key) do
48
- computed = true
49
- value
50
- end
51
- computed ? nil : result
52
- end unless method_defined?(:put_if_absent)
53
-
54
- def value?(value)
55
- each_value do |v|
56
- return true if value.equal?(v)
57
- end
58
- false
59
- end unless method_defined?(:value?)
60
-
61
- def keys
62
- arr = []
63
- each_pair {|k, v| arr << k}
64
- arr
65
- end unless method_defined?(:keys)
66
-
67
- def values
68
- arr = []
69
- each_pair {|k, v| arr << v}
70
- arr
71
- end unless method_defined?(:values)
72
-
73
- def each_key
74
- each_pair {|k, v| yield k}
75
- end unless method_defined?(:each_key)
76
-
77
- def each_value
78
- each_pair {|k, v| yield v}
79
- end unless method_defined?(:each_value)
80
-
81
- def empty?
82
- each_pair {|k, v| return false}
83
- true
84
- end unless method_defined?(:empty?)
85
-
86
- def size
87
- count = 0
88
- each_pair {|k, v| count += 1}
89
- count
90
- end unless method_defined?(:size)
91
-
92
- def marshal_dump
93
- raise TypeError, "can't dump hash with default proc" if @default_proc
94
- h = {}
95
- each_pair {|k, v| h[k] = v}
96
- h
97
- end
98
-
99
- def marshal_load(hash)
100
- initialize
101
- populate_from(hash)
102
- end
103
-
104
- undef :freeze
105
-
106
- private
107
- def initialize_copy(other)
108
- super
109
- populate_from(other)
110
- end
111
-
112
- def populate_from(hash)
113
- hash.each_pair {|k, v| self[k] = v}
114
- self
115
- end
116
-
117
- def validate_options_hash!(options)
118
- if (initial_capacity = options[:initial_capacity]) && (!initial_capacity.kind_of?(Fixnum) || initial_capacity < 0)
119
- raise ArgumentError, ":initial_capacity must be a positive Fixnum"
120
- end
121
- if (load_factor = options[:load_factor]) && (!load_factor.kind_of?(Numeric) || load_factor <= 0 || load_factor > 1)
122
- raise ArgumentError, ":load_factor must be a number between 0 and 1"
123
- end
124
- end
125
- end
126
- end