consul-templaterb 1.9.2 → 1.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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