mirror of
https://github.com/discourse/discourse.git
synced 2024-11-29 12:05:31 +08:00
108 lines
2.3 KiB
Ruby
108 lines
2.3 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
class TemporaryRedis
|
||
|
REDIS_TEMP_DIR = "/tmp/discourse_temp_redis"
|
||
|
REDIS_LOG_PATH = "#{REDIS_TEMP_DIR}/redis.log"
|
||
|
REDIS_PID_PATH = "#{REDIS_TEMP_DIR}/redis.pid"
|
||
|
|
||
|
attr_reader :instance
|
||
|
|
||
|
def initialize
|
||
|
set_redis_server_bin
|
||
|
end
|
||
|
|
||
|
def port
|
||
|
@port ||= find_free_port(11000..11900)
|
||
|
end
|
||
|
|
||
|
def start
|
||
|
return if @started
|
||
|
FileUtils.rm_rf(REDIS_TEMP_DIR)
|
||
|
Dir.mkdir(REDIS_TEMP_DIR)
|
||
|
FileUtils.touch(REDIS_LOG_PATH)
|
||
|
|
||
|
puts "Starting redis on port: #{port}"
|
||
|
@thread = Thread.new do
|
||
|
system(
|
||
|
@redis_server_bin,
|
||
|
"--port", port.to_s,
|
||
|
"--pidfile", REDIS_PID_PATH,
|
||
|
"--logfile", REDIS_LOG_PATH,
|
||
|
"--databases", "1",
|
||
|
"--save", '""',
|
||
|
"--appendonly", "no",
|
||
|
"--daemonize", "no",
|
||
|
"--maxclients", "100",
|
||
|
"--dir", REDIS_TEMP_DIR
|
||
|
)
|
||
|
end
|
||
|
|
||
|
puts "Waiting for redis server to start..."
|
||
|
success = false
|
||
|
instance = nil
|
||
|
config = {
|
||
|
port: port,
|
||
|
host: "127.0.0.1",
|
||
|
db: 0
|
||
|
}
|
||
|
start = Time.now
|
||
|
while !success
|
||
|
begin
|
||
|
instance = DiscourseRedis.new(config, namespace: true)
|
||
|
success = instance.ping == "PONG"
|
||
|
rescue Redis::CannotConnectError
|
||
|
ensure
|
||
|
if !success && (Time.now - start) >= 5
|
||
|
STDERR.puts "ERROR: Could not connect to redis in 5 seconds."
|
||
|
self.remove
|
||
|
exit(1)
|
||
|
elsif !success
|
||
|
sleep 0.1
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
puts "Redis is ready"
|
||
|
@instance = instance
|
||
|
@started = true
|
||
|
end
|
||
|
|
||
|
def remove
|
||
|
if @instance
|
||
|
@instance.shutdown
|
||
|
@thread.join
|
||
|
puts "Redis has been shutdown."
|
||
|
end
|
||
|
FileUtils.rm_rf(REDIS_TEMP_DIR)
|
||
|
@started = false
|
||
|
puts "Redis files have been cleaned up."
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def set_redis_server_bin
|
||
|
path = `which redis-server 2> /dev/null`.strip
|
||
|
if path.size < 1
|
||
|
STDERR.puts 'ERROR: redis-server is not installed on this machine. Please install it'
|
||
|
exit(1)
|
||
|
end
|
||
|
@redis_server_bin = path
|
||
|
rescue => ex
|
||
|
STDERR.puts 'ERROR: Failed to find redis-server binary:'
|
||
|
STDERR.puts ex.inspect
|
||
|
exit(1)
|
||
|
end
|
||
|
|
||
|
def find_free_port(range)
|
||
|
range.each do |port|
|
||
|
return port if port_available?(port)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def port_available?(port)
|
||
|
TCPServer.open(port).close
|
||
|
true
|
||
|
rescue Errno::EADDRINUSE
|
||
|
false
|
||
|
end
|
||
|
end
|