Class: GlobalErrorHandler::RedisNotificationSubscriber

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

Overview

:nodoc:

Defined Under Namespace

Classes: SubscriptionError

Class Method Summary collapse

Class Method Details

.check_redis_configObject



54
55
56
57
58
59
60
61
# File 'lib/global_error_handler/redis_notification_subscriber.rb', line 54

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



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

def redis
  @redis ||= Redis.initialize_redis_from_config
end

.sub_channelObject



50
51
52
# File 'lib/global_error_handler/redis_notification_subscriber.rb', line 50

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

.subscribe!Object



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
42
43
44
# File 'lib/global_error_handler/redis_notification_subscriber.rb', line 12

def subscribe!
  check_redis_config
  begin
    fail 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}"
        Redis.delete_dependencies(key) if key =~ /#{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



63
64
65
# File 'lib/global_error_handler/redis_notification_subscriber.rb', line 63

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

.unsubscribe!Object



6
7
8
9
10
# File 'lib/global_error_handler/redis_notification_subscriber.rb', line 6

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