# frozen_string_literal: true require 'redis' module Pears module Provider # Config using redis subscription. This updates automatically upon Redis # channel updates. # This class would register as "alternative classes with different interfaces". # I ought to clean this up and maybe make "triggers" a different entity # from a provider available in the builder. class Subscription < Base attr_reader :subscription def initialize(channel=nil, redis_host: Pears.config.redis_host, **opts, &fetcher) @builder = opts[:builder] || Builder.new(nil) @channel = channel # Fetcher is a "Provider" of some sort. @fetcher = fetcher # Setup redis subscription establish_connection(redis_host) reload subscribe end def channel @channel ||= @builder.channel_name end def reload @builder.freeze_layers do @data = @fetcher.call.data end end # This seems a bit "rough" of an approach. we should check if # unsubscribing can be done more gracefully. def unsubscribe @subscription.terminate end private def subscribe @subscription = Thread.new do connection.subscribe(@channel) do |on| on.message do |channel, message| reload end end end end def connection @connection ||= establish_connection end def establish_connection(host='redis') @connection = ::Redis.new(host: host, reconnect_attempts: 10, reconnect_delay: 5) end end end end