Module: Legion::Region

Includes:
Logging::Helper
Defined in:
lib/legion/region.rb,
lib/legion/region/failover.rb

Defined Under Namespace

Modules: Failover

Constant Summary collapse

UNSET =
Object.new.freeze
EXPECTED_METADATA_ERRORS =
[
  Net::OpenTimeout,
  Net::ReadTimeout,
  Errno::EHOSTUNREACH,
  Errno::ECONNREFUSED,
  Errno::ENETUNREACH,
  IOError,
  SocketError
].freeze

Class Method Summary collapse

Class Method Details

.affinity_for(message_region, affinity) ⇒ Object



47
48
49
50
51
52
53
# File 'lib/legion/region.rb', line 47

def affinity_for(message_region, affinity)
  return :local if local?(message_region) || affinity == 'any'
  return :remote if affinity == 'prefer_local'
  return :reject if affinity == 'require_local'

  :local
end

.currentObject



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/legion/region.rb', line 22

def current
  setting = defined?(Legion::Settings) ? Legion::Settings.dig(:region, :current) : nil
  return setting unless blank_region?(setting)

  @detected_region = UNSET unless instance_variable_defined?(:@detected_region)
  return nil if @detected_region.equal?(UNSET) && @metadata_detection_complete == true
  return @detected_region unless @detected_region.equal?(UNSET)

  @detected_region = 
  @metadata_detection_complete = true
  @detected_region
rescue StandardError => e
  Legion::Logging.debug "Region#current failed: #{e.message}" if defined?(Legion::Logging)
  nil
end

.detect_aws_regionObject



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/legion/region.rb', line 89

def detect_aws_region
  uri = URI('http://169.254.169.254/latest/meta-data/placement/region')
  token_uri = URI('http://169.254.169.254/latest/api/token')

  token = Net::HTTP.start(token_uri.host, token_uri.port, open_timeout: 1, read_timeout: 1) do |http|
    req = Net::HTTP::Put.new(token_uri)
    req['X-aws-ec2-metadata-token-ttl-seconds'] = '21600'
    http.request(req).body
  end

  Net::HTTP.start(uri.host, uri.port, open_timeout: 1, read_timeout: 1) do |http|
    req = Net::HTTP::Get.new(uri)
    req['X-aws-ec2-metadata-token'] = token
    response = http.request(req)
    response.is_a?(Net::HTTPSuccess) ? response.body.strip : nil
  end
rescue *EXPECTED_METADATA_ERRORS
  nil
rescue StandardError => e
  Legion::Logging.debug "Region#detect_aws_region failed: #{e.message}" if defined?(Legion::Logging)
  nil
end

.detect_azure_regionObject



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/legion/region.rb', line 112

def detect_azure_region
  uri = URI('http://169.254.169.254/metadata/instance/compute/location?api-version=2021-02-01&format=text')

  Net::HTTP.start(uri.host, uri.port, open_timeout: 1, read_timeout: 1) do |http|
    req = Net::HTTP::Get.new(uri)
    req['Metadata'] = 'true'
    response = http.request(req)
    response.is_a?(Net::HTTPSuccess) ? response.body.strip : nil
  end
rescue *EXPECTED_METADATA_ERRORS
  nil
rescue StandardError => e
  Legion::Logging.debug "Region#detect_azure_region failed: #{e.message}" if defined?(Legion::Logging)
  nil
end

.detect_from_metadataObject



82
83
84
85
86
87
# File 'lib/legion/region.rb', line 82

def 
  detect_aws_region || detect_azure_region
rescue StandardError => e
  Legion::Logging.debug "Region#detect_from_metadata failed: #{e.message}" if defined?(Legion::Logging)
  nil
end

.failoverObject



64
65
66
67
68
69
70
71
# File 'lib/legion/region.rb', line 64

def failover
  return nil unless defined?(Legion::Settings)

  Legion::Settings.dig(:region, :failover)
rescue StandardError => e
  Legion::Logging.debug "Region#failover failed: #{e.message}" if defined?(Legion::Logging)
  nil
end

.local?(target_region) ⇒ Boolean

Returns:

  • (Boolean)


43
44
45
# File 'lib/legion/region.rb', line 43

def local?(target_region)
  target_region.nil? || target_region == current
end

.peersObject



73
74
75
76
77
78
79
80
# File 'lib/legion/region.rb', line 73

def peers
  return [] unless defined?(Legion::Settings)

  Legion::Settings.dig(:region, :peers) || []
rescue StandardError => e
  Legion::Logging.debug "Region#peers failed: #{e.message}" if defined?(Legion::Logging)
  []
end

.primaryObject



55
56
57
58
59
60
61
62
# File 'lib/legion/region.rb', line 55

def primary
  return nil unless defined?(Legion::Settings)

  Legion::Settings.dig(:region, :primary)
rescue StandardError => e
  Legion::Logging.debug "Region#primary failed: #{e.message}" if defined?(Legion::Logging)
  nil
end

.reset!Object



38
39
40
41
# File 'lib/legion/region.rb', line 38

def reset!
  remove_instance_variable(:@detected_region) if instance_variable_defined?(:@detected_region)
  remove_instance_variable(:@metadata_detection_complete) if instance_variable_defined?(:@metadata_detection_complete)
end