Class: Karafka::Web::Pro::Ui::Lib::SafeRunner

Inherits:
Object
  • Object
show all
Includes:
Core::Helpers::Time
Defined in:
lib/karafka/web/pro/ui/lib/safe_runner.rb

Overview

Class used to execute code that can fail but we do not want to fail the whole operation. The primary use-case is for displaying deserialized data. We always need to assume, that part of the data can be corrupted and it should not crash the whole UI.

It caches the result and does not run the code twice (only once). Additionally, it measures the CPU usage and total time during the execution of the code block.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(&block) ⇒ SafeRunner

Returns a new instance of SafeRunner.

Parameters:

  • block (Proc)

    code we want to safe-guard



48
49
50
51
52
53
54
55
56
57
# File 'lib/karafka/web/pro/ui/lib/safe_runner.rb', line 48

def initialize(&block)
  @code = block
  @executed = false
  @success = false
  @error = nil
  @result = nil
  @cpu_time = 0
  @total_time = 0
  @allocations = false
end

Instance Attribute Details

#allocationsObject (readonly)

Returns the value of attribute allocations.



45
46
47
# File 'lib/karafka/web/pro/ui/lib/safe_runner.rb', line 45

def allocations
  @allocations
end

#cpu_timeObject (readonly)

Returns the value of attribute cpu_time.



45
46
47
# File 'lib/karafka/web/pro/ui/lib/safe_runner.rb', line 45

def cpu_time
  @cpu_time
end

#errorObject (readonly)

Returns the value of attribute error.



45
46
47
# File 'lib/karafka/web/pro/ui/lib/safe_runner.rb', line 45

def error
  @error
end

#resultObject (readonly)

Returns the value of attribute result.



45
46
47
# File 'lib/karafka/web/pro/ui/lib/safe_runner.rb', line 45

def result
  @result
end

#total_timeObject (readonly)

Returns the value of attribute total_time.



45
46
47
# File 'lib/karafka/web/pro/ui/lib/safe_runner.rb', line 45

def total_time
  @total_time
end

Instance Method Details

#callObject

Runs the execution and returns block result



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/karafka/web/pro/ui/lib/safe_runner.rb', line 74

def call
  return @result if executed?

  @executed = true

  if objspace?
    GC.disable
    ObjectSpace.trace_object_allocations_start
    before = ObjectSpace.each_object.count
  end

  # We measure time as close to the process as possible so it is not impacted by the
  # objects allocations count (if applicable)
  start_time = monotonic_now
  start_cpu = ::Process.times
  @result = @code.call
  @success = true

  @result
rescue => e
  @error = e
  @success = false
ensure
  end_time = monotonic_now
  end_cpu = ::Process.times

  @cpu_time = (
    (end_cpu.utime - start_cpu.utime) + (end_cpu.stime - start_cpu.stime)
  ) * 1_000
  @total_time = (end_time - start_time)

  if objspace?
    @allocations = ObjectSpace.each_object.count - before
    ObjectSpace.trace_object_allocations_stop
    GC.enable
  end
end

#executed?Boolean

Returns was the code executed already or not yet.

Returns:

  • (Boolean)

    was the code executed already or not yet



113
114
115
# File 'lib/karafka/web/pro/ui/lib/safe_runner.rb', line 113

def executed?
  @executed
end

#failure?Boolean

Returns was the code execution failed or not.

Returns:

  • (Boolean)

    was the code execution failed or not



69
70
71
# File 'lib/karafka/web/pro/ui/lib/safe_runner.rb', line 69

def failure?
  !success?
end

#success?Boolean

Returns was the code execution successful or not.

Returns:

  • (Boolean)

    was the code execution successful or not



60
61
62
63
64
65
66
# File 'lib/karafka/web/pro/ui/lib/safe_runner.rb', line 60

def success?
  return @success if executed?

  call

  @success
end