Class: Consul::Async::ConsulTemplateEngine

Inherits:
Object
  • Object
show all
Defined in:
lib/consul/async/consul_template_engine.rb

Overview

The Engine keeps tracks of all templates, handle hot-reload of files if needed as well as ticking the clock to compute state of templates periodically.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeConsulTemplateEngine

Returns a new instance of ConsulTemplateEngine.



16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/consul/async/consul_template_engine.rb', line 16

def initialize
  @templates = []
  @template_callbacks = []
  @hot_reload_failure = 'die'
  @all_templates_rendered = false
  @template_frequency = 1
  @periodic_started = false
  @debug_memory = false
  @result = 0
  @last_memory_state = build_memory_info
  @start = Time.now
end

Instance Attribute Details

#debug_memoryObject

Returns the value of attribute debug_memory.



14
15
16
# File 'lib/consul/async/consul_template_engine.rb', line 14

def debug_memory
  @debug_memory
end

#hot_reload_failureObject

Returns the value of attribute hot_reload_failure.



14
15
16
# File 'lib/consul/async/consul_template_engine.rb', line 14

def hot_reload_failure
  @hot_reload_failure
end

#resultObject (readonly)

Returns the value of attribute result.



14
15
16
# File 'lib/consul/async/consul_template_engine.rb', line 14

def result
  @result
end

#template_frequencyObject

Returns the value of attribute template_frequency.



14
15
16
# File 'lib/consul/async/consul_template_engine.rb', line 14

def template_frequency
  @template_frequency
end

#template_managerObject (readonly)

Returns the value of attribute template_manager.



14
15
16
# File 'lib/consul/async/consul_template_engine.rb', line 14

def template_manager
  @template_manager
end

#templatesObject (readonly)

Returns the value of attribute templates.



14
15
16
# File 'lib/consul/async/consul_template_engine.rb', line 14

def templates
  @templates
end

Instance Method Details

#add_template(source, dest, params = {}) ⇒ Object



42
43
44
# File 'lib/consul/async/consul_template_engine.rb', line 42

def add_template(source, dest, params = {})
  @templates.push([source, dest, params])
end

#add_template_callback(&block) ⇒ Object



38
39
40
# File 'lib/consul/async/consul_template_engine.rb', line 38

def add_template_callback(&block)
  @template_callbacks << block
end

#build_memory_infoObject



29
30
31
32
33
34
35
36
# File 'lib/consul/async/consul_template_engine.rb', line 29

def build_memory_info
  s = GC.stat
  {
    pages: s[:total_allocated_pages] - s[:total_freed_pages],
    objects: s[:total_allocated_objects] - s[:total_freed_objects],
    time: Time.now.utc
  }
end

#do_run(template_manager, template_renders) ⇒ Object

Run templating engine once



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
# File 'lib/consul/async/consul_template_engine.rb', line 47

def do_run(template_manager, template_renders)
  unless template_manager.running
    ::Consul::Async::Debug.puts_info '[FATAL] TemplateManager has been stopped, stopping everything'
    @result = 3
    EventMachine.stop
    return
  end
  results = template_renders.map(&:run)
  all_ready = results.all?(&:ready?)
  if !@all_templates_rendered && all_ready
    @all_templates_rendered = true
    cur_time = Time.now
    ::Consul::Async::Debug.puts_info "First rendering of #{results.count} templates completed in #{cur_time - @start}s at #{cur_time}.  "
  end
  begin
    @template_callbacks.each do |c|
      c.call([all_ready, template_manager, results])
    end
  rescue StandardError => e
    ::Consul::Async::Debug.puts_error "callback error: #{e.inspect}"
    raise e
  end
rescue Consul::Async::InvalidTemplateException => e
  warn "[FATAL]#{e}"
  template_manager.terminate
  @result = 1
  EventMachine.stop
rescue StandardError => e
  warn "[FATAL] Error occured: #{e.inspect} - #{e.backtrace.join("\n\t")}"
  template_manager.terminate
  @result = 2
  EventMachine.stop
end

#do_run_fast(template_manager, template_renders) ⇒ Object

Run template engine as fast as possible until first rendering occurs



82
83
84
85
86
87
88
89
90
91
# File 'lib/consul/async/consul_template_engine.rb', line 82

def do_run_fast(template_manager, template_renders)
  do_run(template_manager, template_renders)

  return if @all_templates_rendered || @periodic_started

  # We continue if rendering not done and periodic not started
  EventMachine.next_tick do
    do_run_fast(template_manager, template_renders)
  end
end

#run(template_manager) ⇒ Object



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
# File 'lib/consul/async/consul_template_engine.rb', line 93

def run(template_manager)
  @template_manager = template_manager
  EventMachine.run do
    template_renders = []
    @templates.each do |template_file, output_file, params|
      template_renders << Consul::Async::ConsulTemplateRender.new(template_manager, template_file, output_file,
                                                                  hot_reload_failure: hot_reload_failure,
                                                                  params: params)
    end
    # Initiate first run immediately to speed up rendering
    EventMachine.next_tick do
      do_run_fast(template_manager, template_renders)
    end
    EventMachine.add_periodic_timer(template_frequency) do
      @periodic_started = true
      do_run(template_manager, template_renders)
      if debug_memory
        GC.start
        new_memory_state = build_memory_info
        diff_allocated = new_memory_state[:pages] - @last_memory_state[:pages]
        diff_num_objects = new_memory_state[:objects] - @last_memory_state[:objects]
        if diff_allocated != 0 || diff_num_objects.abs > (@last_memory_state[:pages] / 3)
          timediff = new_memory_state[:time] - @last_memory_state[:time]
          warn "[MEMORY] #{new_memory_state[:time]} significant RAM Usage detected\n" \
                      "[MEMORY] #{new_memory_state[:time]} Pages  : #{new_memory_state[:pages]}" \
                      " (diff #{diff_allocated} aka #{(diff_allocated / timediff).round(0)}/s) \n" \
                      "[MEMORY] #{new_memory_state[:time]} Objects: #{new_memory_state[:objects]}"\
                      " (diff #{diff_num_objects} aka #{(diff_num_objects / timediff).round(0)}/s)"
          @last_memory_state = new_memory_state
        end
      end
    end
  end
  @result
end