FEATURE: basic implementation of stats socket

This commit is contained in:
Sam 2017-04-21 10:24:43 -04:00
parent 15e2f55655
commit 52306c393a
2 changed files with 100 additions and 0 deletions

63
lib/stats_socket.rb Normal file
View File

@ -0,0 +1,63 @@
require 'socket'
class StatsSocket
def initialize(socket_path)
@socket_path = socket_path
@server = nil
end
def start
@server = UNIXServer.new(@socket_path)
@accept_thread = new_accept_thread
end
def stop
@server.close if @server
@server = nil
end
protected
def new_accept_thread
server = @server
Thread.new do
done = false
while !done
done = !accept_connection(server)
end
end
end
def accept_connection(server)
socket = nil
begin
socket = server.accept
rescue IOError
# socket was shut down or something catastrophic like that happened
return false
end
line = socket.readline
socket.write get_response(line.strip)
socket.close
true
rescue IOError
# nothing to do here, case its normal on shutdown
rescue => e
Rails.logger.warn("Failed to handle connection in stats socket #{e}")
end
def get_response(command)
result =
case command
when "gc_stat"
GC.stat.to_json
else
"[\"UNKNOWN COMMAND\"]"
end
result << "\n"
end
end

View File

@ -0,0 +1,37 @@
require 'rails_helper'
require_dependency 'stats_socket'
describe StatsSocket do
let :socket_path do
"#{Dir.tmpdir}/#{SecureRandom.hex}"
end
let :stats_socket do
StatsSocket.new(socket_path)
end
before do
stats_socket.start
end
after do
stats_socket.stop
end
it "can respond to various stats commands" do
line = nil
# ensure this works more than once :)
2.times do
socket = UNIXSocket.new(socket_path)
socket.send "gc_stat\n", 0
line = socket.readline
socket.close
end
parsed = JSON.parse(line)
expect(parsed.keys.sort).to eq(GC.stat.keys.map(&:to_s).sort)
end
end