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



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

def agent
  @agent
end

#app_rootString (readonly)

Application root directory, in absolute file path form.

Returns:

  • (String)


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

def app_root
  @app_root
end

#on_breakpoints_changeMethod

Callback function invoked when new breakpoints are added or removed

Returns:

  • (Method)


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

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:



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

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.



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

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 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.



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

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:



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

def breakpoints
  synchronize do
    @active_breakpoints | @completed_breakpoints
  end
end

#clear_breakpointsObject

Clear local breakpoints cache. Remove all active and completed breakpoints



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

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:



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

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:



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

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.



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

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.



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

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 =
    convert_grpc_breakpoints response.breakpoints || []

  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:



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

def update_breakpoints server_breakpoints
  synchronize do
    new_breakpoints =
      filter_breakpoints server_breakpoints - breakpoints

    before_breakpoints_count = 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 = 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