Hubert Łepicki
Warsaw Ruby Users Group, 17.05.2017
Fault tolerance is the property that enables a system to continue operating properly in the event of the failure of (or one or more faults within) some of its components.
random people from Wikipedia
(...) fault tolerance is the ability for software to detect and recover from a fault that is happening (...)
https://users.ece.cmu.edu/~koopman/des_s99/sw_fault_tolerance/
"Of course 5 years from now that will be different, but 5 years from now everyone will be running free GNU on their 200 MIPS, 64M SPARCstation-5."
begin
...
rescue SomeExceptionClass => error
logger.info "Exception caught"
...
end
begin
...
rescue SomeExceptionClass, SomeOther => error
logger.info "Exception caught"
...
end
begin
...
rescue SomeException => e
...
rescue SomeOther => e
...
end
tries = 0
begin
tries += 1
...
rescue
retry if tries < 4
...
end
begin
AWSWrapper.some_external_operation
rescue StandardError => error
logger.error "Exception intercepted calling AWSWrapper"
logger.error error.message
logger.error error.backtrace.join("\n")
end
require 'timeout'
begin
Timeout::timeout(3) do
AWSWrapper.some_external_operation
end
rescue StandardError => error
logger.error "Exception intercepted calling AWSWrapper"
logger.error error.message
logger.error error.backtrace.join("\n")
end
unicorn master -c /app/unicorn.rb -E production -D
unicorn worker[0] -c /app/unicorn.rb -E production -D
unicorn worker[1] -c /app/unicorn.rb -E production -D
unicorn worker[2] -c /app/unicorn.rb -E production -D
unicorn worker[3] -c /app/unicorn.rb -E production -D
(look for timeout option)
require 'circuit_breaker'
class ApiWrapper
include CircuitBreaker
def call_remote_service
...
end
circuit_method :call_remote_service
end
SEMIAN_PARAMETERS = { tickets: 1,
success_threshold: 1,
error_threshold: 3,
error_timeout: 10 }
Semian::NetHTTP.semian_configuration = proc do |host, port|
# Let's make it only active for www.wrug.eu
if host == "www.wrug.eu"
SEMIAN_PARAMETERS.merge(name: "wrug.eu")
else
nil
end
end
class Counter
# This is all you have to do to turn any Ruby
# class into one which creates
# Celluloid actors instead of normal objects
include Celluloid
# Now just define methods like you ordinarily would
attr_reader :count
def initialize
@count = 0
end
def increment(n = 1)
@count += n
end
end
actor = Counter.new
p actor.count
# Log *all* exceptions thrown by *all* actors in the system
Celluloid.exception_handler { |ex| MyNotifier.notify(ex) }
# Reference your actors by name
Celluloid::Actor[:itchy] = Itchy.new
Actor[:itchy].scratch()
# Supervise your actors
class MyGroup < Celluloid::SupervisionGroup
supervise Itchy, as: :itchy
end
Koichi Sasada
http://www.atdot.net/~ko1/activities/2016_rubykaigi.pdf
https://www.youtube.com/watch?v=WIrYh14H9kA&feature=youtu.be