Class: Fly::Configuration

Inherits:
Object
  • Object
show all
Defined in:
lib/fly-ruby/configuration.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeConfiguration

Returns a new instance of Configuration.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/fly-ruby/configuration.rb', line 36

def initialize
  self.primary_region = ENV["PRIMARY_REGION"]
  self.current_region = ENV["FLY_REGION"]
  self.replay_http_methods = ["POST", "PUT", "PATCH", "DELETE"]
  self.database_url_env_var = "DATABASE_URL"
  self.redis_url_env_var = "REDIS_URL"
  self.database_host_env_var = "DATABASE_HOST"
  self.database_port_env_var = "DATABASE_PORT"
  self.replay_threshold_cookie = "fly-replay-threshold"
  self.replay_threshold_in_seconds = 5
  self.database_url = ENV[database_url_env_var]
  self.redis_url = ENV[redis_url_env_var]
  self.replayable_exceptions = ["SQLite3::CantOpenException", "PG::ReadOnlySqlTransaction"]
end

Instance Attribute Details

#current_regionObject

Set the region where this instance of the application is deployed



6
7
8
# File 'lib/fly-ruby/configuration.rb', line 6

def current_region
  @current_region
end

#database_host_env_varObject

Returns the value of attribute database_host_env_var.



18
19
20
# File 'lib/fly-ruby/configuration.rb', line 18

def database_host_env_var
  @database_host_env_var
end

#database_port_env_varObject

Returns the value of attribute database_port_env_var.



19
20
21
# File 'lib/fly-ruby/configuration.rb', line 19

def database_port_env_var
  @database_port_env_var
end

#database_urlObject

Returns the value of attribute database_url.



30
31
32
# File 'lib/fly-ruby/configuration.rb', line 30

def database_url
  @database_url
end

#database_url_env_varObject

Environment variables related to the database connection. These get by this middleware in secondary regions, so they must be interpolated rather than defined directly in the configuration.



17
18
19
# File 'lib/fly-ruby/configuration.rb', line 17

def database_url_env_var
  @database_url_env_var
end

#primary_regionObject

Set the region where the primary database lives, i.e “ams”



9
10
11
# File 'lib/fly-ruby/configuration.rb', line 9

def primary_region
  @primary_region
end

#redis_urlObject

Returns the value of attribute redis_url.



31
32
33
# File 'lib/fly-ruby/configuration.rb', line 31

def redis_url
  @redis_url
end

#redis_url_env_varObject

Returns the value of attribute redis_url_env_var.



20
21
22
# File 'lib/fly-ruby/configuration.rb', line 20

def redis_url_env_var
  @redis_url_env_var
end

#replay_http_methodsObject

Automatically replay these HTTP methods in the primary region



12
13
14
# File 'lib/fly-ruby/configuration.rb', line 12

def replay_http_methods
  @replay_http_methods
end

Cookie written and read by this middleware storing a UNIX timestamp. Requests arriving before this timestamp will be replayed in the primary region.



24
25
26
# File 'lib/fly-ruby/configuration.rb', line 24

def replay_threshold_cookie
  @replay_threshold_cookie
end

#replay_threshold_in_secondsObject

How long, in seconds, should all requests from the same client be replayed in the primary region after a successful write replay



28
29
30
# File 'lib/fly-ruby/configuration.rb', line 28

def replay_threshold_in_seconds
  @replay_threshold_in_seconds
end

#replayable_exceptionsObject

An array of string representations of exceptions that should trigger a replay



34
35
36
# File 'lib/fly-ruby/configuration.rb', line 34

def replayable_exceptions
  @replayable_exceptions
end

Instance Method Details

#console?Boolean

Is the current process a Rails console?

Returns:

  • (Boolean)


130
131
132
# File 'lib/fly-ruby/configuration.rb', line 130

def console?
  defined?(::Rails::Console) && $stdout.isatty && $stdin.isatty
end

#database_app_nameObject



67
68
69
# File 'lib/fly-ruby/configuration.rb', line 67

def database_app_name
  database_uri.hostname.split(".")[-2] || database_uri.hostname
end

#database_domainObject



71
72
73
# File 'lib/fly-ruby/configuration.rb', line 71

def database_domain
  "#{database_app_name}.internal"
end

#database_uriObject



63
64
65
# File 'lib/fly-ruby/configuration.rb', line 63

def database_uri
  @database_uri ||= URI.parse(database_url)
end

#eligible_for_activation?Boolean

Returns:

  • (Boolean)


115
116
117
# File 'lib/fly-ruby/configuration.rb', line 115

def eligible_for_activation?
  database_url && primary_region && current_region && !rake_task?
end

#hijack_database_connection!Object



119
120
121
122
123
# File 'lib/fly-ruby/configuration.rb', line 119

def hijack_database_connection!
  # Don't reset the database URL for on-disk sqlite
  return if database_uri.scheme.start_with?("sqlite") || database_uri.host !~ /(internal|localhost)/
  ENV["DATABASE_URL"] = in_secondary_region? ? secondary_database_url : primary_database_url
end

#in_secondary_region?Boolean

Returns:

  • (Boolean)


125
126
127
# File 'lib/fly-ruby/configuration.rb', line 125

def in_secondary_region?
  primary_region && primary_region != current_region
end

#module_exists?(module_name) ⇒ Boolean

Returns:

  • (Boolean)


56
57
58
59
60
61
# File 'lib/fly-ruby/configuration.rb', line 56

def module_exists?(module_name)
  mod = Module.const_get(module_name)
  return mod
rescue NameError
  nil
end

#primary_database_urlObject



75
76
77
78
79
80
# File 'lib/fly-ruby/configuration.rb', line 75

def primary_database_url
  uri = database_uri.dup
  uri.host = "#{primary_region}.#{database_domain}"
  uri.port = secondary_database_port
  uri.to_s
end

#rake_task?Boolean

Is the current process a rake task?

Returns:

  • (Boolean)


135
136
137
# File 'lib/fly-ruby/configuration.rb', line 135

def rake_task?
  defined?(::Rake) && !Rake.application.top_level_tasks.empty?
end

#redis_uriObject



100
101
102
103
# File 'lib/fly-ruby/configuration.rb', line 100

def redis_uri
  @redis_uri ||= URI.parse(redis_url)
  @redis_uri
end

#regional_redis_hostObject



105
106
107
# File 'lib/fly-ruby/configuration.rb', line 105

def regional_redis_host
  "#{current_region}.#{redis_uri.hostname}"
end

#regional_redis_urlObject



109
110
111
112
113
# File 'lib/fly-ruby/configuration.rb', line 109

def regional_redis_url
  uri = redis_uri.dup
  uri.host = regional_redis_host
  uri.to_s
end

#replayable_exception_classesObject



51
52
53
54
# File 'lib/fly-ruby/configuration.rb', line 51

def replayable_exception_classes
  @replayable_exception_classes ||= replayable_exceptions.collect {|ex| module_exists?(ex) }.compact
  @replayable_exception_classes
end

#secondary_database_portObject



89
90
91
92
93
94
95
96
97
98
# File 'lib/fly-ruby/configuration.rb', line 89

def secondary_database_port
  port = if in_secondary_region?
    case database_uri.scheme
    when "postgres"
      5433
    end
  end

  port || database_uri.port
end

#secondary_database_urlObject



82
83
84
85
86
87
# File 'lib/fly-ruby/configuration.rb', line 82

def secondary_database_url
  uri = database_uri.dup
  uri.host = "top1.nearest.of.#{database_domain}"
  uri.port = secondary_database_port
  uri.to_s
end

#web?Boolean

Returns:

  • (Boolean)


139
140
141
# File 'lib/fly-ruby/configuration.rb', line 139

def web?
  !console? && !rake_task?
end