Skip to content

Instantly share code, notes, and snippets.

@kohgpat
Created June 6, 2013 07:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kohgpat/5719943 to your computer and use it in GitHub Desktop.
Save kohgpat/5719943 to your computer and use it in GitHub Desktop.
require 'redis'
require 'json'
require 'celluloid'
require 'celluloid/io'
class RedisAdapter
include Celluloid
def initialize(redis)
@redis = redis
end
def record(path)
redis.incr("stats:#{path}")
end
def fetch(path)
redis.get("stats:#{path}")
end
protected
attr_reader :redis
end
class Stats
include Celluloid
def handle(msg)
log(msg)
case msg
when %r{^VISIT (.*)$}
path = $1
puts path
redis.async.record(path)
"OK\n"
when %r{^STATS (.*)$}
path = $1
puts path
stats = redis.fetch(path)
JSON.dump(stats: {path => stats})
else
"ERR\n"
end
end
def log(msg)
Celluloid.logger.info(msg)
end
def redis
Celluloid::Actor[:redis]
end
end
class Listener
include Celluloid::IO
def initialize(host, port)
log("Starting on #{host}:#{port}")
@server = TCPServer.new(host, port)
async.run
end
def finalize
return unless @server
@server.close
end
def run
loop {
async.handle_connection(@server.accept)
}
end
def handle_connection(socket)
_, host, port = socket.peeraddr
log("#{host}:#{port} connected")
msg = socket.readpartial(4096)
response = stats.handle(msg)
socket.write(response)
socket.close
rescue EOFError
log("#{host}:#{port} disconnected")
socket.close
end
def log(msg)
puts msg
end
def stats
Celluloid::Actor[:stats]
end
end
class Collector < Celluloid::SupervisionGroup
supervise Stats, as: :stats
supervise RedisAdapter, as: :redis, args: [Redis.new]
supervise Listener, as: :listener, args: ["0.0.0.0", 3000]
end
if __FILE__ == $0
collector = Collector.run!
trap("INT") do
collector.terminate
exit
end
sleep
end
require 'socket'
socket = TCPSocket.open('localhost', 3000)
socket.write("STATS /")
puts socket.read
socket.close
require 'socket'
socket = TCPSocket.open('localhost', 3000)
socket.write("VISIT /")
puts socket.read
socket.close
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment