class Consul::Async::ConsulTemplateEngine

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.

Attributes

debug_memory[RW]
hot_reload_failure[RW]
result[R]
template_frequency[RW]
template_manager[R]
templates[R]

Public Class Methods

new() click to toggle source
# 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

Public Instance Methods

add_template(source, dest, params = {}) click to toggle source
# 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) click to toggle source
# File lib/consul/async/consul_template_engine.rb, line 38
def add_template_callback(&block)
  @template_callbacks << block
end
build_memory_info() click to toggle source
# 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) click to toggle source

Run templating engine once

# 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) click to toggle source

Run template engine as fast as possible until first rendering occurs

# 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) click to toggle source
# 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