Class: GlobalErrorHandler::RedisNotificationSubscriber

Inherits:
Object
  • Object
show all
Defined in:
lib/global_error_handler/redis_notification_subscriber.rb

Defined Under Namespace

Classes: SubscriptionError

Class Method Summary collapse

Class Method Details

.check_redis_configObject



51
52
53
54
55
56
57
58
# File 'lib/global_error_handler/redis_notification_subscriber.rb', line 51

def check_redis_config
  # x     Expired events (events generated every time a key expires)
  # g     Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...
  # A     Alias for g$lshzxe, so that the "AKE" string means all the events.
  # E     Keyevent events, published with __keyevent@<db>__ prefix.
  ### AE|gE|xE|AKE|gKE|xKE
  redis.config('set', 'notify-keyspace-events', 'xE') unless redis.config('get', 'notify-keyspace-events').last =~ /[Agx]+.?E/
end

.redisObject



43
44
45
# File 'lib/global_error_handler/redis_notification_subscriber.rb', line 43

def redis
  GlobalErrorHandler::Redis.redis
end

.sub_channelObject



47
48
49
# File 'lib/global_error_handler/redis_notification_subscriber.rb', line 47

def sub_channel
  @sub_channel ||= "__keyevent@#{self.redis.client.db}__:expired"
end

.subscribe!Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/global_error_handler/redis_notification_subscriber.rb', line 9

def subscribe!
  check_redis_config
  begin
    raise SubscriptionError, "wont subscribe to ##{sub_channel}. Someone already listening to this channel" if subscribers_count > 0
    redis.subscribe(sub_channel) do |on|
      puts "*** ##{Process.pid}: Listeting for the notifications on ##{sub_channel}..."
      on.message do |channel, key|
        puts "**** ##{channel}: #{key}"
        GlobalErrorHandler::Redis.delete_dependencies(key) if key =~ /#{GlobalErrorHandler::Redis.exception_key("\\d+")}/
      end
      on.subscribe do |channel, subscriptions|
        puts "##{Process.pid}: Subscribed to ##{channel} (#{subscriptions} subscriptions)"
      end

      on.unsubscribe do |channel, subscriptions|
        puts "##{Process.pid}: Unsubscribed from ##{channel} (#{subscriptions} subscriptions)"
      end
    end
  rescue Redis::BaseConnectionError => error
    puts "##{Process.pid}: #{error}, retrying in 1s"
    sleep 1
    retry
  rescue SubscriptionError => error
    puts "##{Process.pid}: #{error}, retrying in 1s"
    sleep 1
    retry
  rescue Interrupt => error
    puts "##{Process.pid}: unsubscribing..."
    unsubscribe!
    redis.quit
    redis.client.reconnect
  end
end

.subscribers_countObject



60
61
62
# File 'lib/global_error_handler/redis_notification_subscriber.rb', line 60

def subscribers_count
  redis.publish sub_channel, "check subscribers count from ##{Process.pid}"
end

.unsubscribe!Object



5
6
7
# File 'lib/global_error_handler/redis_notification_subscriber.rb', line 5

def unsubscribe!
  redis.unsubscribe(sub_channel) rescue nil
end