Class: Google::Cloud::Debugger::BreakpointManager

Inherits:
Object
  • Object
show all
Includes:
MonitorMixin
Defined in:
lib/google/cloud/debugger/breakpoint_manager.rb

Overview

BreakpointManager

Responsible for querying Stackdriver Debugger service for any active breakpoints and keep an accurate local copies of the breakpoints.

It correctly remembers which breakpoints are currently active and watched by the debugger agent, and which breakpoints are already completed. The BreakpointManager holds the record of truth for debugger breakpoints

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#agentGoogle::Cloud::Debugger::Agent (readonly)

The debugger agent this tracer belongs to



38
39
40
# File 'lib/google/cloud/debugger/breakpoint_manager.rb', line 38

def agent
  @agent
end

#app_rootString (readonly)

Application root directory, in absolute file path form.

Returns:

  • (String)


47
48
49
# File 'lib/google/cloud/debugger/breakpoint_manager.rb', line 47

def app_root
  @app_root
end

#on_breakpoints_changeMethod

Callback function invoked when new breakpoints are added or removed

Returns:

  • (Method)


52
53
54
# File 'lib/google/cloud/debugger/breakpoint_manager.rb', line 52

def on_breakpoints_change
  @on_breakpoints_change
end

Instance Method Details

#active_breakpointsArray<Google::Cloud::Debugger::Breakpoint>

Get a list of all active breakpoints.

Returns:



246
247
248
249
250
# File 'lib/google/cloud/debugger/breakpoint_manager.rb', line 246

def active_breakpoints
  synchronize do
    @active_breakpoints
  end
end

#all_complete?Boolean

Check whether any active breakpoints haven't been completed yet.

Returns:

  • (Boolean)

    True if no more active breakpoints are left. False otherwise.



257
258
259
260
261
# File 'lib/google/cloud/debugger/breakpoint_manager.rb', line 257

def all_complete?
  synchronize do
    @active_breakpoints.empty?
  end
end

#breakpoint_hit(breakpoint, call_stack_bindings) ⇒ Object

Evaluates a hit breakpoint, and submit the breakpoint to Transmitter if this breakpoint is evaluated successfully.

See Google::Cloud::Debugger::Breakpoint#evaluate for evaluation details.

Parameters:

  • breakpoint (Google::Cloud::Debugger::Breakpoint)

    The breakpoint to be evaluated

  • call_stack_bindings (Array<Binding>)

    An array of Ruby Binding objects, from the each frame of the call stack that leads to the triggering of the breakpoints.



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/google/cloud/debugger/breakpoint_manager.rb', line 154

def breakpoint_hit breakpoint, call_stack_bindings
  breakpoint.evaluate call_stack_bindings

  case breakpoint.action
  when :CAPTURE
    # Take this completed breakpoint off manager's active breakpoints
    # list, submit the breakpoint snapshot, and update Tracer's
    # breakpoints_cache.
    return unless breakpoint.complete?

    # Remove this breakpoint from active list
    mark_off breakpoint
    # Signal transmitter to submit this breakpoint
    agent.transmitter.submit breakpoint
  when :LOG
    log_logpoint breakpoint
  end
end

#breakpointsArray<Google::Cloud::Debugger::Breakpoint>

Get a list of all breakpoints, both active and completed.

Returns:



224
225
226
227
228
# File 'lib/google/cloud/debugger/breakpoint_manager.rb', line 224

def breakpoints
  synchronize do
    @active_breakpoints | @completed_breakpoints
  end
end

#clear_breakpointsObject

Clear local breakpoints cache. Remove all active and completed breakpoints



266
267
268
269
270
271
# File 'lib/google/cloud/debugger/breakpoint_manager.rb', line 266

def clear_breakpoints
  synchronize do
    @active_breakpoints.clear
    @completed_breakpoints.clear
  end
end

#completed_breakpointsArray<Google::Cloud::Debugger::Breakpoint>

Get a list of all completed breakpoints.

Returns:



235
236
237
238
239
# File 'lib/google/cloud/debugger/breakpoint_manager.rb', line 235

def completed_breakpoints
  synchronize do
    @completed_breakpoints
  end
end

#log_logpoint(logpoint) ⇒ Object

Assume the given logpoint is successfully evaluated, log the evaluated log message via logger

Parameters:



179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/google/cloud/debugger/breakpoint_manager.rb', line 179

def log_logpoint logpoint
  return unless agent.logger && logpoint.evaluated_log_message

  message = "LOGPOINT: #{logpoint.evaluated_log_message}"

  case logpoint.log_level
  when :INFO
    agent.logger.info message
  when :WARNING
    agent.logger.warn message
  when :ERROR
    agent.logger.error message
  end
end

#mark_off(breakpoint) ⇒ Google::Cloud::Debugger::Breakpoint, NilClass

Mark a given active breakpoint as completed. Meaning moving it from list of active breakpoints to completed breakpoints.

Parameters:

Returns:

  • (Google::Cloud::Debugger::Breakpoint, NilClass)

    The same breakpoint if successfully marked off as completed. Nil if this breakpoint isn't found in the list of active breakpoints or failed to mark off as completed.



206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/google/cloud/debugger/breakpoint_manager.rb', line 206

def mark_off breakpoint
  synchronize do
    breakpoint = @active_breakpoints.delete breakpoint

    if breakpoint.nil?
      nil
    else
      @completed_breakpoints << breakpoint
      breakpoint
    end
  end
end

#sync_active_breakpoints(debuggee_id) ⇒ Boolean

Sync active breakpoints with Stackdriver Debugger service for a given debuggee application. Each request to the debugger service returns the full list of all active breakpoints. This method makes sure the local cache of active breakpoints is consistent with server breakpoints set.

Parameters:

  • debuggee_id (String)

    Debuggee application ID

Returns:

  • (Boolean)

    True if synced successfully; otherwise false.



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/google/cloud/debugger/breakpoint_manager.rb', line 84

def sync_active_breakpoints debuggee_id
  begin
    response = service.list_active_breakpoints debuggee_id, @wait_token
  rescue
    return false
  end

  return true if response.wait_expired

  @wait_token = response.next_wait_token

  server_breakpoints = response.breakpoints || []
  server_breakpoints = server_breakpoints.map do |grpc_b|
    Breakpoint.from_grpc grpc_b
  end

  update_breakpoints server_breakpoints

  true
end

#update_breakpoints(server_breakpoints) ⇒ Object

Update the local breakpoints cache with a list of server active breakpoints. New breakpoints will be added to local cache, and deleted breakpoints will be removed from local cache.

It also correctly identifies evaluated active breakpoints from the server set of breakpoints, and does not re-add such evaluated breakpoints to the active list again.

Parameters:



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/google/cloud/debugger/breakpoint_manager.rb', line 117

def update_breakpoints server_breakpoints
  synchronize do
    new_breakpoints =
      server_breakpoints - @active_breakpoints - @completed_breakpoints
    before_breakpoints_count =
      @active_breakpoints.size + @completed_breakpoints.size

    # Remember new active breakpoints from server
    @active_breakpoints += new_breakpoints unless new_breakpoints.empty?

    # Forget old breakpoints
    @completed_breakpoints &= server_breakpoints
    @active_breakpoints &= server_breakpoints
    after_breakpoints_acount =
      @active_breakpoints.size + @completed_breakpoints.size

    breakpoints_updated =
      !new_breakpoints.empty? ||
      (before_breakpoints_count != after_breakpoints_acount)

    on_breakpoints_change.call(@active_breakpoints) if
      on_breakpoints_change.respond_to?(:call) && breakpoints_updated
  end
end