Class: Canopus::Diagnostics::Registry

Inherits:
Object
  • Object
show all
Defined in:
lib/canopus/diagnostics.rb,
sig/diagnostics.rbs

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize ⇒ void #initialize ⇒ void

Returns a new instance of Registry.

Overloads:

  • #initialize ⇒ void
  • #initialize ⇒ void

Yields:

Yield Parameters:

  • arg0 (String)

Yield Returns:

  • (void)


23
24
25
26
27
28
29
30
31
# File 'lib/canopus/diagnostics.rb', line 23

def initialize(&on_change)
  @entries = {}
  @sizes = {}
  @counts = SEVERITIES.keys.to_h { |severity| [severity, 0] }
  @total = @bytes = 0
  @lock = Mutex.new
  @on_change = on_change
  @version = 0
end

Instance Attribute Details

#version ⇒ Integer (readonly)

Returns the value of attribute version.

Returns:

  • (Integer)


21
22
23
# File 'lib/canopus/diagnostics.rb', line 21

def version
  @version
end

Instance Method Details

#all(severity: nil, source: nil) ⇒ Array[Entry]

Parameters:

  • severity: (Integer, severity, nil) (defaults to: nil)
  • source: (source, nil) (defaults to: nil)

Returns:



71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/canopus/diagnostics.rb', line 71

def all(severity: nil, source: nil)
  severity = normalize_severity(severity) if severity
  source = normalize_source(source) if source
  @lock.synchronize do
    @entries.flat_map do |(entry_source, uri), diagnostics|
      next [] if source && source != entry_source

      diagnostics.filter_map do |diagnostic|
        next if severity && diagnostic.fetch("severity", 1) != severity
        Entry.new(entry_source, uri, diagnostic).freeze
      end
    end.freeze
  end
end

#counts ⇒ {error: Integer, warning: Integer, information: Integer, hint: Integer}

Returns:

  • ({error: Integer, warning: Integer, information: Integer, hint: Integer})


86
87
88
# File 'lib/canopus/diagnostics.rb', line 86

def counts
  @lock.synchronize { @counts.dup.freeze }
end

#for_uri(uri) ⇒ Array[Entry]

Parameters:

  • uri (String)

Returns:



62
63
64
65
66
67
68
69
# File 'lib/canopus/diagnostics.rb', line 62

def for_uri(uri)
  uri = normalize_uri(uri)
  @lock.synchronize do
    @entries.flat_map do |(source, current), diagnostics|
      current == uri ? diagnostics.map { |diagnostic| Entry.new(source, current, diagnostic).freeze } : []
    end.freeze
  end
end

#publish(source, uri, diagnostics, notify: true) ⇒ Array[Sadr::object]

Parameters:

  • source (source)
  • uri (String)
  • diagnostics (Array[Sadr::object])
  • notify: (Boolean) (defaults to: true)

Returns:

  • (Array[Sadr::object])

Raises:

  • (ArgumentError)


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
59
60
# File 'lib/canopus/diagnostics.rb', line 33

def publish(source, uri, diagnostics, notify: true)
  raise ArgumentError, "invalid diagnostics notification option" unless [true, false].include?(notify)
  source = normalize_source(source)
  uri = normalize_uri(uri)
  values, bytes = normalize_diagnostics(diagnostics)
  @lock.synchronize do
    key = [source, uri]
    previous = @entries.fetch(key, [])
    total = @total - previous.length + values.length
    raise ArgumentError, "too many diagnostics" if total > TOTAL_LIMIT
    total_bytes = @bytes - @sizes.fetch(key, 0) + bytes
    raise ArgumentError, "diagnostics use too much memory" if total_bytes > TOTAL_BYTES_LIMIT

    previous.each { |diagnostic| @counts[SEVERITIES.key(diagnostic.fetch("severity", 1))] -= 1 }
    values.each { |diagnostic| @counts[SEVERITIES.key(diagnostic.fetch("severity", 1))] += 1 }
    if values.empty?
      @entries.delete(key)
      @sizes.delete(key)
    else
      @entries[key] = values
      @sizes[key] = bytes
    end
    @total, @bytes = total, total_bytes
    @version += 1
  end
  @on_change&.call(uri) if notify
  values
end