mirror of
https://github.com/discourse/discourse.git
synced 2024-11-28 04:53:39 +08:00
112 lines
2.4 KiB
Ruby
112 lines
2.4 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(11_000..11_900)
|
||
|
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 { |port| return port if port_available?(port) }
|
||
|
end
|
||
|
|
||
|
def port_available?(port)
|
||
|
TCPServer.open(port).close
|
||
|
true
|
||
|
rescue Errno::EADDRINUSE
|
||
|
false
|
||
|
end
|
||
|
end
|