Skip to content

Commit

Permalink
Improved timeout pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
ankane committed Feb 27, 2023
1 parent ccb1751 commit b9a23a7
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 20 deletions.
33 changes: 17 additions & 16 deletions app/controllers/pg_hero/home_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,18 @@ def index

@transaction_id_danger = @database.transaction_id_danger(threshold: 1500000000)

sequences = rescue_lock_timeout { @database.sequences } || []
sequences, @sequences_timeout = rescue_timeout([]) { @database.sequences }
@readable_sequences, @unreadable_sequences = sequences.partition { |s| s[:readable] }

@sequence_danger = @database.sequence_danger(threshold: (params[:sequence_threshold] || 0.9).to_f, sequences: @readable_sequences)

# TODO improve rescue_lock_timeout pattern
@sequence_timeout = @lock_timeout
@lock_timeout = false

@indexes = rescue_lock_timeout { @database.indexes } || []
@indexes, @indexes_timeout =
if @sequences_timeout
# skip indexes for faster loading
[[], true]
else
rescue_timeout([]) { @database.indexes }
end
@invalid_indexes = @database.invalid_indexes(indexes: @indexes)
@invalid_constraints = @database.invalid_constraints
@duplicate_indexes = @database.duplicate_indexes(indexes: @indexes)
Expand Down Expand Up @@ -85,7 +87,7 @@ def space
@days = (params[:days] || 7).to_i
@database_size = @database.database_size
@only_tables = params[:tables].present?
@relation_sizes = rescue_lock_timeout { @only_tables ? @database.table_sizes : @database.relation_sizes } || []
@relation_sizes, @sizes_timeout = rescue_timeout([]) { @only_tables ? @database.table_sizes : @database.relation_sizes }
@space_stats_enabled = @database.space_stats_enabled? && !@only_tables
if @space_stats_enabled
space_growth = @database.space_growth(days: @days, relation_sizes: @relation_sizes)
Expand Down Expand Up @@ -199,7 +201,7 @@ def show_query

if @tables.any?
@row_counts = @database.table_stats(table: @tables).to_h { |i| [i[:table], i[:estimated_rows]] }
indexes = rescue_lock_timeout { @database.indexes } || []
indexes, @indexes_timeout = rescue_timeout([]) { @database.indexes }
@indexes_by_table = indexes.group_by { |i| i[:table] }
end
else
Expand Down Expand Up @@ -448,18 +450,18 @@ def set_query_stats_enabled
end

def set_suggested_indexes(min_average_time = 0, min_calls = 0)
if @database.suggested_indexes_enabled?
@indexes ||= rescue_lock_timeout { @database.indexes } || []
if @database.suggested_indexes_enabled? && !@indexes
@indexes, @indexes_timeout = rescue_timeout([]) { @database.indexes }
end

@suggested_indexes_by_query =
if !@lock_timeout && @database.suggested_indexes_enabled?
if !@indexes_timeout && @database.suggested_indexes_enabled?
@database.suggested_indexes_by_query(query_stats: @query_stats.select { |qs| qs[:average_time] >= min_average_time && qs[:calls] >= min_calls }, indexes: @indexes)
else
{}
end

@suggested_indexes = @lock_timeout ? {} : @database.suggested_indexes(suggested_indexes_by_query: @suggested_indexes_by_query)
@suggested_indexes = @database.suggested_indexes(suggested_indexes_by_query: @suggested_indexes_by_query)
@query_stats_by_query = @query_stats.index_by { |q| q[:query] }
@debug = params[:debug].present?
end
Expand Down Expand Up @@ -510,11 +512,10 @@ def ensure_query_stats

# rescue QueryCanceled for case when
# statement timeout is less than lock timeout
def rescue_lock_timeout
yield
def rescue_timeout(default)
[yield, false]
rescue ActiveRecord::LockWaitTimeout, ActiveRecord::QueryCanceled
@lock_timeout = true
nil
[default, true]
end
end
end
4 changes: 2 additions & 2 deletions app/views/pg_hero/home/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@
Vacuuming healthy
<% end %>
</div>
<div class="alert alert-<%= @sequence_danger && @sequence_danger.empty? && !@sequence_timeout ? "success" : "warning" %>">
<div class="alert alert-<%= @sequence_danger && @sequence_danger.empty? && !@sequences_timeout ? "success" : "warning" %>">
<% if @sequence_danger.any? %>
<%= pluralize(@sequence_danger.size, "column") %> approaching overflow
<% elsif @sequence_timeout %>
<% elsif @sequences_timeout %>
Sequences not available (system catalog locked)
<% else %>
No columns near integer overflow
Expand Down
2 changes: 1 addition & 1 deletion app/views/pg_hero/home/show_query.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
<td><%= table %></td>
<td><%= @row_counts[table] %></td>
<td>
<% if @lock_timeout %>
<% if @indexes_timeout %>
Not available
<% else %>
<ul>
Expand Down
2 changes: 1 addition & 1 deletion app/views/pg_hero/home/space.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
</div>
<% end %>
<% if @lock_timeout %>
<% if @sizes_timeout %>
<p>Breakdown not available (system catalog locked)</p>
<% else %>
<table class="table space-table">
Expand Down

0 comments on commit b9a23a7

Please sign in to comment.