Module: Startback::Support::Robustness

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.



99
100
101
# File 'lib/startback/support/robustness.rb', line 99

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.



106
107
108
109
110
111
112
113
# File 'lib/startback/support/robustness.rb', line 106

def monitor(*args, &bl)
  result = nil
  took = Benchmark.realtime {
    result = bl.call
  }
  Tools.info(args, op_took: took)
  result
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.



120
121
122
123
124
125
126
127
128
129
# File 'lib/startback/support/robustness.rb', line 120

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.



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

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