Module: Startback::Support::Robustness

Included in:
Bus, Bus::Bunny::Async, Bus::Memory::Async, Bus::Memory::Sync, Caching::EntityCache, Web::CatchAll
Defined in:
lib/startback/support/robustness.rb

Overview

This module provides helper methods for robustness of a software design.

It is included by main Startback abstractions, and can be included by specific software components who needs fine-tuning of monitoring, logging and error handling.

All public methods here follow the following free args parameters:

  1. First (& second) argument(s) form the log message.

    A full log message is a Hash having :op (required), :op_took (optional), and :op_data (optional) keys.

    If a String (or two) are used instead, a log message will be built taking the former as the executer (a class or instance) and the second as a method. ‘{ op: “executer#method” }`

  2. The second (or third) argument should be a Logger instance, a Context, or an instance knowing its context. The best logger is extracted from it and used for actual logging.

Examples:

log(:info, op: "hello", op_data: {foo: 12})    => logged as such on STDOUT
log(:info, "A simple message")                 => { op: "A simple message" } on STDOUT
log(:info, Startback, "hello")                 => { op: "Startback#hello"  } on STDOUT
log(:info, Event.new, "hello")                 => { op: "Event#hello" }      on STDOUT
log(:info, Event.new, "hello", "hello world")  => { op: "Event#hello", op_data: { message: "hello world" } } on STDOUT
log(:info, self, context)                      => { op: "..." } on context's logger or STDOUT
log(:info, self, event)                        => { op: "..." } on event context's logger or STDOUT
...

Defined Under Namespace

Modules: Tools

Instance Method Summary collapse

Instance Method Details

#log(severity, *args) ⇒ Object

Logs a specific message with a given severity.

Severity can be :debug, :info, :warn, :error or :fatal. The args must follow module’s conventions, see above.



94
95
96
# File 'lib/startback/support/robustness.rb', line 94

def log(severity, *args)
  Tools.send(severity, args)
end

#monitor(*args, &bl) ⇒ Object

Calls the block and monitors then log its execution time.

The args must follow module’s conventions, see above.



101
102
103
104
105
106
107
108
109
110
# File 'lib/startback/support/robustness.rb', line 101

def monitor(*args, &bl)
  result = nil
  took = Benchmark.realtime {
    result = bl.call
  }
  Tools.info(args, op_took: took)
  result
rescue => ex
  raise
end

#stop_errors(*args, &bl) ⇒ Object

Executes the block without letting errors propagate. Errors are logged, though. Nothing is logged if everything goes fine.

The args must follow module’s conventions, see above.



117
118
119
120
121
122
123
124
125
126
# File 'lib/startback/support/robustness.rb', line 117

def stop_errors(*args, &bl)
  result = nil
  took = Benchmark.realtime {
    result = bl.call
  }
  result
rescue => ex
  Tools.fatal(args, op_took: took, error: ex)
  nil
end

#try_max_times(n, *args, &bl) ⇒ Object

Tries executing the block up to ‘n` times, until an attempt succeeds (then returning the result). Logs the first and last fatal error, if any.

The args must follow module’s conventions, see above.



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/startback/support/robustness.rb', line 133

def try_max_times(n, *args, &bl)
  retried = 0
  took = 0
  begin
    result = nil
    took += Benchmark.realtime {
      result = bl.call
    }
    result
  rescue => ex
    Tools.error(args + [{op_took: took, error: ex}]) if retried == 0
    retried += 1
    if retried < n
      sleep(retried)
      retry
    else
      Tools.fatal(args + [{op_took: took, error: ex}])
      raise
    end
  end
end