Class: VagrantCloud::Instrumentor::Collection

Inherits:
Core
  • Object
show all
Defined in:
lib/vagrant_cloud/instrumentor/collection.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(instrumentors: []) ⇒ Collection

Create a new instance

Parameters:

  • instrumentors (Array<Core>) (defaults to: [])

    Instrumentors to add to collection



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/vagrant_cloud/instrumentor/collection.rb', line 12

def initialize(instrumentors: [])
  @lock = Mutex.new
  @subscriptions = Set.new
  @instrumentors = Set.new
  # Add our default
  @instrumentors << Logger.new

  Array(instrumentors).each do |i|
    if !i.is_a?(Core) && !i.respond_to?(:instrument)
      raise TypeError, "Instrumentors must implement `#instrument`"
    end
    @instrumentors << i
  end
  @instrumentors.freeze
end

Instance Attribute Details

#instrumentorsSet<Instrumentor::Core> (readonly)

Returns:



5
6
7
# File 'lib/vagrant_cloud/instrumentor/collection.rb', line 5

def instrumentors
  @instrumentors
end

#subscriptionsSet<Callable> (readonly)

Returns:

  • (Set<Callable>)


7
8
9
# File 'lib/vagrant_cloud/instrumentor/collection.rb', line 7

def subscriptions
  @subscriptions
end

Instance Method Details

#add(instrumentor) ⇒ self

Add a new instrumentor

Parameters:

  • instrumentor (Core)

    New instrumentor to add

Returns:

  • (self)


32
33
34
35
36
37
38
39
40
41
# File 'lib/vagrant_cloud/instrumentor/collection.rb', line 32

def add(instrumentor)
  @lock.synchronize do
    if !instrumentor.is_a?(Core) && !instrumentor.respond_to?(:instrument)
      raise TypeError, "Instrumentors must implement `#instrument`"
    end

    @instrumentors = (instrumentors + [instrumentor]).freeze
  end
  self
end

#instrument(name, params = {}) ⇒ Object

Call all instrumentors in collection with given parameters



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/vagrant_cloud/instrumentor/collection.rb', line 82

def instrument(name, params = {})
  # Log the start time
  timing = {start_time: Time.now}

  # Run the action
  result = yield if block_given?

  # Log the completion time and calculate duration
  timing[:complete_time] = Time.now
  timing[:duration] = timing[:complete_time] - timing[:start_time]

  # Insert timing into params
  params[:timing] = timing

  # Call any instrumentors we know about
  @lock.synchronize do
    # Call our instrumentors first
    instrumentors.each do |i|
      i.instrument(name, params)
    end
    # Now call any matching subscriptions
    subscriptions.each do |event, callable|
      if event.is_a?(Regexp)
        next if !event.match(name)
      else
        next if event != name
      end
      args = [name, params]

      if callable.arity > -1
        args = args[0, callable.arity]
      end

      callable.call(*args)
    end
  end

  result
end

#remove(instrumentor) ⇒ self

Remove instrumentor

Parameters:

  • instrumentor (Core)

    Remove instrumentor from collection

Returns:

  • (self)


47
48
49
50
51
52
# File 'lib/vagrant_cloud/instrumentor/collection.rb', line 47

def remove(instrumentor)
  @lock.synchronize do
    @instrumentors = instrumentors.dup.tap{|i| i.delete(instrumentor)}.freeze
  end
  self
end

#subscribe(event, callable = nil, &block) ⇒ Object

Add a subscription for events

Parameters:

  • event (Regexp, String)

    Event to match



57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/vagrant_cloud/instrumentor/collection.rb', line 57

def subscribe(event, callable=nil, &block)
  if callable && block
    raise ArgumentError, "Callable argument or block expected, not both"
  end
  c = callable || block
  if !c.respond_to?(:call)
    raise TypeError, "Callable action is required for subscription"
  end
  entry = [event, c]
  @lock.synchronize do
    @subscriptions = (@subscriptions + [entry]).freeze
  end
  self
end

#unsubscribe(callable) ⇒ Object



72
73
74
75
76
77
78
79
# File 'lib/vagrant_cloud/instrumentor/collection.rb', line 72

def unsubscribe(callable)
  @lock.synchronize do
    subscriptions = @subscriptions.dup
    subscriptions.delete_if { |entry| entry.last == callable }
    @subscriptions = subscriptions.freeze
  end
  self
end