consul-templaterb 1.9.2 → 1.9.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 59bf13c2279da7eb5ba1955ca645420d91033cfb8d608a5a881824bf5492d6ed
4
- data.tar.gz: a042648698f120b575308868d60e4dc92dbe47163f5f5c59a7ddd21f7194dac3
3
+ metadata.gz: 5782528a3540e33076a9db4244d558f9e62d846b68f7aa57cb625dbc2cca7415
4
+ data.tar.gz: c3d33c3bb5f760f1b0108807213e8d59aceca92cce6eccb67c32ff759010ece8
5
5
  SHA512:
6
- metadata.gz: 978c146a7bd5f11f5bc3de56e0952c465f0011a24201e3a61268b27a34c4ba641e6f2841bb43911d8a1288c5854147164ed0468dbe3c0f4009e279e8addd724f
7
- data.tar.gz: 63989a0b6cfded326d6ede9698163f68cfab2bda46c12a403814f45c89d49fb679d434c7a769581463fdd6d21f3325fb8910a8fcc279c3dd68bca5d846f659d0
6
+ metadata.gz: 02cb21ad2703bfd0a847181c4b4d0b5bd4a96503130e949db99498461dee4e1744e35b406a056ddcd2023eacc6aac3463e51b33685748a8733dd02fa57852efd
7
+ data.tar.gz: 19015ff464cdeb7ee09b04471d78562b415b02878349c2d9c5bd96acac758276759efdff2132000558b96d3003ac473d29369c47090189fc29cf16178918e3d6
data/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  ## (UNRELEASED)
4
4
 
5
+ ## 1.9.3 (January 9, 2019)
6
+
7
+ IMPROVEMENTS:
8
+
9
+ * Perform some randomization on retries, so in case of massive errors,
10
+ system will likely re-open all connections at the same time.
11
+ * consul-timeline more optimize ringbuffer for larger history
12
+ * UI improvements (tooltips for services/checks)
13
+
5
14
  ## 1.9.2 (January 4, 2019)
6
15
 
7
16
  IMPROVEMENTS:
@@ -137,7 +137,7 @@ module Consul
137
137
  "[#{stats.body_bytes_human.ljust(8)}][#{stats.bytes_per_sec_human.ljust(9)}]"\
138
138
  " #{path.ljust(48)} idx:#{result.x_consul_index}, next in #{result.retry_in} s"
139
139
  end
140
- on_error { |http| STDERR.puts "[ERROR]: #{path}: #{http.error}" }
140
+ on_error { |http| STDERR.puts "[ERROR]: #{path}: #{http.error.inspect}" }
141
141
  end
142
142
 
143
143
  def on_response(&block)
@@ -185,8 +185,12 @@ module Consul
185
185
  http.response_header['X-Consul-Index']
186
186
  end
187
187
 
188
+ def _compute_retry_in(retry_in)
189
+ retry_in / 2 + Consul::Async::Utilities.random.rand(retry_in)
190
+ end
191
+
188
192
  def _handle_error(http, consul_index)
189
- retry_in = [600, conf.retry_duration + 2**@consecutive_errors].min
193
+ retry_in = _compute_retry_in([600, conf.retry_duration + 2**@consecutive_errors].min)
190
194
  STDERR.puts "[ERROR][#{path}] X-Consul-Index:#{consul_index} - #{http.error} - Retry in #{retry_in}s #{stats.body_bytes_human}"
191
195
  @consecutive_errors += 1
192
196
  http_result = HttpResponse.new(http)
@@ -227,6 +231,7 @@ module Consul
227
231
  else
228
232
  retry_in = modified ? conf.min_duration : conf.retry_on_non_diff
229
233
  end
234
+ retry_in = _compute_retry_in(retry_in)
230
235
  retry_in = 0.1 if retry_in < 0.1
231
236
  unless @stopping
232
237
  EventMachine.add_timer(retry_in) do
@@ -33,6 +33,11 @@ module Consul
33
33
  raise "Don't know how to load parameters file #{parameters_file}: JSON and YAML supported"
34
34
  end
35
35
  end
36
+
37
+ def self.random
38
+ @random = Random.new unless @random
39
+ @random
40
+ end
36
41
  end
37
42
  end
38
43
  end
@@ -1,5 +1,5 @@
1
1
  module Consul
2
2
  module Async
3
- VERSION = '1.9.2'.freeze
3
+ VERSION = '1.9.3'.freeze
4
4
  end
5
5
  end
@@ -31,6 +31,7 @@
31
31
  <meta name="description" content="Display Consul information"/>
32
32
  <meta name="author" content="Criteo"/>
33
33
  <title><%= param('title', 'Consul Real Time information') %></title>
34
+ <link rel="icon" type="image/png" href="images/favicon.png" sizes="32x32" />
34
35
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
35
36
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.11/css/all.css" integrity="sha384-p2jx59pefphTFIpeqCcISO9MdVfIm4pNnsL08A6v5vaQc4owkQqxMV8kg4Yvhaw/" crossorigin="anonymous">
36
37
  <link rel="stylesheet" href="css/style.css">
@@ -251,7 +251,7 @@ class ConsulService {
251
251
  serviceHtml.appendChild(tagsGenerator(instance.tags));
252
252
  serviceHtml.appendChild(serviceMetaGenerator(instance.sMeta));
253
253
  serviceHtml.appendChild(connectGenerator(instance))
254
- serviceHtml.appendChild(checksStatusGenerator(instance.checks));
254
+ serviceHtml.appendChild(checksStatusGenerator(instance));
255
255
  serviceHtml.setAttribute('status', state);
256
256
  $("#instances-list").append(serviceHtml);
257
257
  }
@@ -457,7 +457,7 @@ class ServiceTimeline {
457
457
  var checkName = document.createElement('div');
458
458
  checkName.setAttribute('class', 'lookup checkName');
459
459
  checkName.setAttribute('data-toggle', 'tooltip');
460
- checkName.setAttribute('title', c['id']+'\n\n' + c.output);
460
+ checkName.setAttribute('title', 'ID: ' + c['id'] + '\nName: ' + c['name'] + '\n\n' + c.output);
461
461
  checkName.appendChild(document.createTextNode(c['name']));
462
462
  checksCell.appendChild(checkName);
463
463
  }
@@ -52,6 +52,10 @@ function serviceTitleGenerator(instance) {
52
52
  }
53
53
 
54
54
  var htmlTitle = document.createElement('h5');
55
+ htmlTitle.setAttribute('title', 'Node Name: ' + instance.name +
56
+ '\nAddress : ' + instance.addr +
57
+ '\nService ID: ' + instance.id +
58
+ '\nService Port : ' + instance.port);
55
59
 
56
60
  var instanceLink = document.createElement('a');
57
61
  instanceLink.setAttribute('class', 'instance-name');
@@ -223,14 +227,16 @@ function servicesGenerator(instanceServices) {
223
227
  return services;
224
228
  }
225
229
 
226
- function checksStatusGenerator(instanceChecks) {
230
+ function checksStatusGenerator(instance) {
231
+ var instanceChecks = instance.checks;
227
232
  var checks = document.createElement('div');
228
233
  checks.className = 'checks';
229
234
  checks.appendChild(document.createTextNode("Checks: "));
230
235
  checks.appendChild(document.createElement('br'));
231
236
 
232
237
  for (var checkKey in instanceChecks) {
233
- checkId = Math.floor(Math.random()*10000);
238
+ var checkInstance = instanceChecks[checkKey];
239
+ var checkId = instance.name + '::' + checkInstance.checkid;
234
240
  var btn = 'btn-' + toCSSClass(instanceChecks[checkKey]['status'])
235
241
  var check = document.createElement('div');
236
242
 
@@ -240,6 +246,7 @@ function checksStatusGenerator(instanceChecks) {
240
246
  btnCheck.setAttribute('data-toggle', 'collapse');
241
247
  btnCheck.setAttribute('data-target', '#' + checkId);
242
248
  btnCheck.setAttribute('aria-expanded', 'false');
249
+ btnCheck.setAttribute('title', checkInstance.checkid);
243
250
 
244
251
  btnCheck.appendChild(document.createTextNode(instanceChecks[checkKey]['name']));
245
252
 
@@ -0,0 +1,107 @@
1
+ module ConsulTimeline
2
+ class RingBufferNode
3
+ attr_reader :prev, :value, :next
4
+ attr_writer :prev, :next, :value
5
+ def initialize(value, p_elem, n_elem)
6
+ @value = value
7
+ @prev = p_elem
8
+ @next = n_elem
9
+ end
10
+
11
+ # Insert element before current element, return inserted Node
12
+ def insert_before(obj)
13
+ old_prev = @prev
14
+ @prev = RingBufferNode.new(obj, old_prev, self)
15
+ old_prev&.next = @prev
16
+ @prev
17
+ end
18
+
19
+ # Append element after current ince, return inserted Node
20
+ def append(obj)
21
+ old_next = @next
22
+ @next = RingBufferNode.new(obj, self, old_next)
23
+ old_next&.prev = @next
24
+ @next
25
+ end
26
+
27
+ def to_s
28
+ "[prev=#{@prev.object_id}, next=#{@next.object_id}, value=#{@value}]"
29
+ end
30
+ end
31
+ class SortedRingBuffer
32
+ include Enumerable
33
+ def initialize(max_size, sort_func)
34
+ raise "Invalid size #{max_size}" unless max_size.positive?
35
+ @head = RingBufferNode.new(nil, nil, nil)
36
+ @sort_func = sort_func
37
+ @tail = @head
38
+ @max_size = max_size
39
+ (max_size - 1).times do
40
+ @head = @head.insert_before(nil)
41
+ end
42
+ end
43
+
44
+ def push(obj)
45
+ return unless obj
46
+ cur = @tail
47
+ raise "No head.next found in #{@head}" unless @head.next
48
+ while cur && cur.value && @sort_func.call(cur.value, obj).positive?
49
+ cur = cur.prev
50
+ end
51
+ if cur.nil?
52
+ # The value we try to insert is before @head
53
+ # no need to do anything
54
+ elsif cur == @head
55
+ # This is the head, just update the value
56
+ @head.value = obj
57
+ else
58
+ @head = @head.next
59
+ @head.prev = nil
60
+ new_val = cur.append(obj)
61
+ @tail = new_val if @tail == cur
62
+ end
63
+ end
64
+
65
+ def each
66
+ return enum_for(:each) unless block_given? # Sparkling magic!
67
+ cur = @head
68
+ until cur.nil?
69
+ yield cur.value if cur.value
70
+ cur = cur.next
71
+ end
72
+ end
73
+
74
+ def to_a
75
+ arr = Array.new(@max_size)
76
+ cur = @head
77
+ i = 0
78
+ until cur.nil?
79
+ if cur.value
80
+ arr[i] = cur.value
81
+ i += 1
82
+ end
83
+ cur = cur.next
84
+ end
85
+ if i != @max_size
86
+ arr.reject(&:nil?)
87
+ else
88
+ arr
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ if ARGV.count.positive? && ARGV[0] == 'debug'
95
+ require 'json'
96
+ size = (ARGV[1] || 10).to_i
97
+ ringbuff = ConsulTimeline::SortedRingBuffer.new(size, ->(a, b) { a <=> b })
98
+ ringbuff.push 0.5
99
+ puts ringbuff.to_a
100
+ (size * 10).times do |i|
101
+ ringbuff.push(2 * i + Random.rand(size / 10))
102
+ end
103
+ ringbuff.push 99_999_999_999_999
104
+ arr = ringbuff.to_a
105
+ raise "OOPS wrong size := #{arr.count} instead of #{size}" unless arr.count == size
106
+ STDOUT.puts JSON.generate(arr)
107
+ end
@@ -55,33 +55,7 @@ old_state = if @previous_state
55
55
  end
56
56
 
57
57
  unless @events
58
- class RingBuffer < Array
59
- attr_reader :max_size
60
-
61
- def initialize(max_size:, enum: nil)
62
- @max_size = max_size
63
- warn "Ringbuffer initialized with #{max_size}"
64
- enum&.each { |e| self << e }
65
- end
66
-
67
- def <<(element)
68
- return unless element
69
- if size >= @max_size
70
- shift
71
- end
72
- previous_e = last
73
- after = []
74
- while !previous_e.nil? && (previous_e['idx'] > element['idx'])
75
- after.insert(0, pop)
76
- previous_e = last
77
- end
78
- push(element)
79
- after.each do |x|
80
- push(x)
81
- end
82
- self
83
- end
84
- end
58
+ load File.expand_path(File.join(File.dirname(template_info['source']), 'ringbuffer.rb'))
85
59
 
86
60
  def diff(old, new_e)
87
61
  diff = OpenStruct.new
@@ -92,7 +66,7 @@ unless @events
92
66
  diff
93
67
  end
94
68
 
95
- @events = RingBuffer.new(max_size: (ENV['CONSUL_TIMELINE_BUFFER'] || 10000).to_i)
69
+ @events = ::ConsulTimeline::SortedRingBuffer.new((ENV['CONSUL_TIMELINE_BUFFER'] || 10000).to_i, lambda {|a, b| a['idx'] <=> b['idx'] })
96
70
  end
97
71
  @new_events = []
98
72
 
@@ -209,7 +183,7 @@ sorted_events = @new_events.sort do |a, b|
209
183
  end
210
184
  res
211
185
  end
212
- sorted_events.each { |e| @events << e }
186
+ sorted_events.each { |e| @events.push e }
213
187
  @new_events.clear
214
188
 
215
189
  # We save the previous state only when we have a complete state once
@@ -217,4 +191,4 @@ if template_info['was_rendered_once']
217
191
  warn "First full rendering completed at #{@current_time} !" unless @previous_state
218
192
  @previous_state = cur_state
219
193
  end
220
- %><%= JSON.generate(@events) %>
194
+ %><%= JSON.generate(@events.to_a) %>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: consul-templaterb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.2
4
+ version: 1.9.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - SRE Core Services
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-04 00:00:00.000000000 Z
11
+ date: 2019-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: em-http-request
@@ -184,11 +184,13 @@ files:
184
184
  - samples/consul-ui/consul_nodes.json.erb
185
185
  - samples/consul-ui/consul_services.json.erb
186
186
  - samples/consul-ui/css/style.css
187
+ - samples/consul-ui/images/favicon.png
187
188
  - samples/consul-ui/js/keys.js
188
189
  - samples/consul-ui/js/nodes.js
189
190
  - samples/consul-ui/js/service.js
190
191
  - samples/consul-ui/js/timeline.js
191
192
  - samples/consul-ui/js/utils.js
193
+ - samples/consul-ui/ringbuffer.rb
192
194
  - samples/consul-ui/timeline.json.erb
193
195
  - samples/consul-ui/vendors/highlight/atom-one-dark.css
194
196
  - samples/consul-ui/vendors/highlight/highlight.pack.js