Class: TgErrorNotifier::TopicManager

Inherits:
Object
  • Object
show all
Defined in:
lib/tg_error_notifier/topic_manager.rb

Constant Summary collapse

ICON_COLOR_RED =
0xFB6F5F
ICON_COLOR_BLUE =
0x6FB9F0
MAX_TOPIC_NAME =
128
MAX_STORE_KEY =
200

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ TopicManager

Returns a new instance of TopicManager.



14
15
16
17
18
19
20
# File 'lib/tg_error_notifier/topic_manager.rb', line 14

def initialize(config)
  @config = config
  @mutex = Mutex.new
  @condition = ConditionVariable.new
  @topics = {} # grouping_key => message_thread_id
  @creating = Set.new
end

Instance Method Details

#thread_id_for(key, exception) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/tg_error_notifier/topic_manager.rb', line 22

def thread_id_for(key, exception)
  name = nil
  store_key = "exception:#{key}"[0...MAX_STORE_KEY]

  @mutex.synchronize do
    # Wait if another thread is already creating this topic
    while @creating.include?(key)
      @condition.wait(@mutex, 10)
    end

    return @topics[key] if @topics.key?(key)

    # Тема ошибки должна пережить рестарт и быть общей для всех
    # процессов: иначе каждый puma/sidekiq-воркер заводит свой дубль
    stored = store_read(store_key)
    if stored
      @topics[key] = stored
      return stored
    end

    @creating.add(key)
    name = topic_name(exception)
  end

  thread_id = create_topic(name)

  @mutex.synchronize do
    if thread_id
      @topics[key] = thread_id
      store_write(store_key, thread_id)
    end
    @creating.delete(key)
    @condition.broadcast
  end

  thread_id
end

#thread_id_for_name(name) ⇒ Object

Resolve thread_id for an explicitly named topic (capture_message topic: "..."). Unlike exception topics, named topics survive restarts via the configured topic_store_read/topic_store_write callbacks.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/tg_error_notifier/topic_manager.rb', line 63

def thread_id_for_name(name)
  key = "topic:#{name}"

  @mutex.synchronize do
    while @creating.include?(key)
      @condition.wait(@mutex, 10)
    end

    return @topics[key] if @topics.key?(key)

    stored = store_read(name)
    if stored
      @topics[key] = stored
      return stored
    end

    @creating.add(key)
  end

  thread_id = create_topic(truncate_name(name), icon_color: @config.topic_icon_color || ICON_COLOR_BLUE)

  @mutex.synchronize do
    if thread_id
      @topics[key] = thread_id
      store_write(name, thread_id)
    end
    @creating.delete(key)
    @condition.broadcast
  end

  thread_id
end