Skip to content

Commit

Permalink
added support for Redis Sentinel
Browse files Browse the repository at this point in the history
  • Loading branch information
Ithanil committed Apr 22, 2024
1 parent 3f64bef commit 7eb8b71
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 10 deletions.
6 changes: 5 additions & 1 deletion app/controllers/health_checks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ def check_database
end

def check_redis
Redis.new.ping
if Greenlight::Application.config.cache_store == :null_store
Redis.new.ping
else
Redis.new(Greenlight::Application.config.cache_store[1].except(:adapter, :channel_prefix)).ping
end
rescue StandardError => e
raise "Unable to connect to Redis - #{e}"
end
Expand Down
12 changes: 7 additions & 5 deletions bin/start
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ if [ "$RAILS_ENV" = "production" ]; then
sleep 1
done

while ! nc -zw3 $RDHOST $RDPORT
do
echo "Waiting for redis to start up ..."
sleep 1
done
if [ -z "$REDIS_SENTINEL" ]; then
while ! nc -zw3 $RDHOST $RDPORT
do
echo "Waiting for redis to start up ..."
sleep 1
done
fi
fi

rails assets:precompile
Expand Down
6 changes: 5 additions & 1 deletion config/cable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,9 @@ test:

production:
adapter: redis
url: <%= ENV.fetch("REDIS_URL", "") %>
url: <%= ENV.fetch("REDIS_URL", nil) || "redis://mymaster" %>
sentinels: <%= ENV.fetch("REDIS_SENTINEL", "") %>
name: mymaster
role: master
namespace: greenlight3
channel_prefix: greenlight_production
39 changes: 38 additions & 1 deletion config/environments/production.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,43 @@

require 'active_support/core_ext/integer/time'

class String
def string_between_markers(marker1, marker2)
self[/#{Regexp.escape(marker1)}(.*?)#{Regexp.escape(marker2)}/m, 1]
end
end

def parse_sentinels(sentinel_str)
work_str = sentinel_str.gsub(/[[:space:]]/, '').delete_prefix('[').delete_suffix(']') # remove all white space and surrounding []
sentinel_arr = []
until work_str.empty?
# cut string with hash content
sub_str = work_str.string_between_markers('{', '}')
# convert that string to hash (while converting keys to symbols and
# values to integer, if possible, else make it string without single quotes)
sub_arr = sub_str.split(',').map do |h|
h1, h2 = h.split(':')
{ h1.to_sym => h2.match?(/\D/) ? h2.delete("'") : h2.to_i }
end
sub_hash = sub_arr.reduce(:merge)
sentinel_arr.append(sub_hash)
# remove hash string from current working string and delete any surrounding commas
work_str.slice! "{#{sub_str}}"
work_str = work_str.delete_prefix(',').delete_suffix(',')
end
sentinel_arr
end

def config_cache_store
if ENV.fetch('REDIS_SENTINEL', nil).present?
[:redis_cache_store, { sentinels: parse_sentinels(ENV.fetch('REDIS_SENTINEL')),
url: ENV.fetch('REDIS_URL', nil) || 'redis://mymaster',
name: 'mymaster', role: :master }]
else
[:redis_cache_store, { url: ENV.fetch('REDIS_URL', nil) }]
end
end

Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.

Expand Down Expand Up @@ -111,7 +148,7 @@
config.log_tags = [:request_id]

# Use a different cache store in production.
config.cache_store = :redis_cache_store, { url: ENV.fetch('REDIS_URL', nil) }
config.cache_store = config_cache_store

# Use a real queuing backend for Active Job (and separate queues per environment).
config.active_job.queue_adapter = :async # TODO: Configure :resque
Expand Down
7 changes: 5 additions & 2 deletions sample.env
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ BIGBLUEBUTTON_SECRET=
# E.g. postgres://postgres:password@postgres:5432/greenlight-v3-production
DATABASE_URL=

### REDIS CACHE URL
# Must be in the format redis://host:port
### REDIS CACHE
# REDIS_URL: Must be in the format redis://host:port
# E.g. redis://redis:6379
# REDIS_SENTINEL: Must be an array of host, port pairs. In this case leave REDIS_URL blank or set it to e.g. redis://mymaster.
# E.g. [{host: 'host1', port: 26379}, {host: 'host2', port: 26379}, {host: 'host3', port: 26379}]
REDIS_URL=
REDIS_SENTINEL=

### OPTIONAL ENV VARS

Expand Down

0 comments on commit 7eb8b71

Please sign in to comment.