-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathplot_visibility_timeout.rb
141 lines (111 loc) · 5.08 KB
/
plot_visibility_timeout.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
require './../lib/eventq/eventq_aws/aws_calculate_visibility_timeout'
require 'csv'
require 'logger'
class PlotVisibilityTimeout
# Folder where the plot results are saved
PLOT_FOLDER = 'plot_results'
def plot(settings)
setup
@plot_seconds = settings.fetch(:plot_seconds)
@plot_min_timeout = settings.fetch(:plot_min_timeout)
@plot_file_name = "#{PLOT_FOLDER}/plot_#{settings.values.join('__')}"
@queue_allow_retry_back_off = settings.fetch(:queue_allow_retry_back_off)
@queue_allow_exponential_back_off = settings.fetch(:queue_allow_exponential_back_off)
@queue_retry_back_off_weight = settings.fetch(:queue_retry_back_off_weight)
@queue_retry_jitter_ratio = settings.fetch(:queue_retry_jitter_ratio)
@queue_max_retry_delay = settings.fetch(:queue_max_retry_delay)
@queue_max_timeout = settings.fetch(:queue_max_timeout)
@queue_retry_back_off_grace = settings.fetch(:queue_retry_back_off_grace)
@queue_retry_delay = settings.fetch(:queue_retry_delay)
logger = Logger.new(STDOUT)
@calculator = EventQ::Amazon::CalculateVisibilityTimeout.new(max_timeout: @queue_max_timeout, logger: logger)
print_settings_list(settings)
execute
end
private
attr_reader :calculator
def setup
unless Dir.exist?(PLOT_FOLDER)
Dir.mkdir(PLOT_FOLDER)
end
end
def execute
puts "Executing..."
CSV.open("#{@plot_file_name}.csv", 'w') do |csv|
csv << ['retry_counter', 'visibility_timeout', 'total_elapsed_time', ]
retry_counter = 0
total_elapsed_time = 0
max_visibility_timeout = 0
while(total_elapsed_time <= @plot_seconds) do
retry_counter += 1
visibility_timeout = calculate(retry_counter)
if (visibility_timeout == 0)
visibility_timeout = @plot_min_timeout
end
max_visibility_timeout = visibility_timeout
total_elapsed_time += visibility_timeout
total_elapsed_time = total_elapsed_time.round(2)
csv << [retry_counter, visibility_timeout, total_elapsed_time]
end
print_output(retry_counter, max_visibility_timeout,total_elapsed_time)
end
end
def calculate(retry_counter)
calculator.call(
retry_attempts: retry_counter,
queue_settings: {
allow_retry_back_off: @queue_allow_retry_back_off,
allow_exponential_back_off: @queue_allow_exponential_back_off,
max_retry_delay: @queue_max_retry_delay,
retry_back_off_grace: @queue_retry_back_off_grace,
retry_back_off_weight: @queue_retry_back_off_weight,
retry_jitter_ratio: @queue_retry_jitter_ratio,
retry_delay: @queue_retry_delay
}
)
end
def print_settings_list(settings)
settings_list = [
"-" * 50,
settings.map { |arr| "#{arr[0]} = #{arr[1]}" }.join("\n"),
"-" * 50,
"\n"
].join("\n")
puts settings_list
File.write("#{@plot_file_name}.txt", settings_list)
end
def print_output(retry_counter, max_visibility_timeout,total_elapsed_time)
output_details = [
"Completed:",
"• #{retry_counter} total retries.",
"• #{retry_counter - @queue_retry_back_off_grace} total retries after grace period.",
"• #{max_visibility_timeout} max timeout in seconds",
"• #{total_elapsed_time} total elapsed time in seconds"
].join("\n")
puts output_details
puts "=> #{@plot_file_name}.csv"
File.open("#{@plot_file_name}.txt", 'a') { |f| f.write(output_details) }
end
end
settings = {
# Sometimes the calculated timeout is zero so we must default to a value
# since in real life the is no zero second connections.
plot_min_timeout: 0.03, # 30ms which is the average connection time between worker and queue
# The amount of time we should plot for.
plot_seconds: 72*60*60, # simulate 72h
queue_allow_retry_back_off: true, # enables backoff strategy
queue_allow_exponential_back_off: false, # disables exponential backoff strategy
# The cap value for the queue retry
queue_max_retry_delay: 1_500_000, # will wait max 1500s
queue_max_timeout: 43_200, # 12h which AWS max message visibility timeout
# Waiting period before the backoff strategy kicks in.
# Multiply with query_retry_delay and divide by 60 to see how many minutes it will wait.
queue_retry_back_off_grace: 30_000, # wait 15min: (queue_retry_back_off_grace * queue_retry_delay)/60
# Delay and retry for each queue iterations. The multiplier is necessary in case the calculated values
# are insignificant between iterations.
queue_retry_back_off_weight: 100, # Backoff multiplier
queue_retry_delay: 30, # 30ms
# Ratio of randomness allowed on retry delay to avoid a bulk of retries hitting again at the same time
queue_retry_jitter_ratio: 0 # ratio for randomness on retry delay
}
PlotVisibilityTimeout.new.plot(settings)