RnD-Soft/lusnoc

View on GitHub
lib/lusnoc/guard.rb

Summary

Maintainability
A
0 mins
Test Coverage
require 'timeouter'
require 'lusnoc/helper'

module Lusnoc
  class Guard

    include Helper

    attr_reader :callbacks

    def initialize(base_url)
      @base_url = base_url
      @callbacks = {}
      yield(self) if block_given?
    end

    def condition(&block)
      @callbacks[:condition] = block
      self
    end

    def then(&block)
      @callbacks[:then] = block
      self
    end

    def run
      th = start_thread
      yield
    ensure
      th.kill rescue nil
    end

    private

      def start_thread
        Thread.new do
          logger.info "Guard[#{@base_url.inspect}] thread started"
          watch_forever(@base_url)
          fire!
        rescue StandardError => e
          logger.error "Guard[#{@base_url.inspect}] error: #{e.inspect}"
          logger.error e.backtrace
          fire!(e)
        ensure
          logger.info "Guard[#{@base_url.inspect}] finihsed"
        end
      end

      def fire!(*args)
        @callbacks[:then]&.tap do |cb|
          @callbacks[:then] = nil
          logger.info "Guard[#{@base_url.inspect}] fired"
          cb.call(*args)
        end
      end

      def watch_forever(base_url)
        Lusnoc::Watcher.new(base_url).run(max_consul_wait: 10) do |body|
          return true unless @callbacks[:condition].call(body)
        end
      end

      # def watch_forever(base_url)
      #   last_x_consul_index = 1

      #   Kernel.loop do
      #     resp = Lusnoc.http_get("#{base_url}?index=#{last_x_consul_index}&wait=10s", timeout: 15)
      #     logger.debug "Guard[#{@base_url.inspect}] response: #{resp.body}"
      #     return unless @callbacks[:condition].call(resp.body)

      #     index = [Integer(resp['x-consul-index']), 1].max
      #     last_x_consul_index = (index < last_x_consul_index ? 1 : index)
      #     sleep 0.4
      #   end
      # end

  end
end