Created
June 6, 2013 07:43
-
-
Save kohgpat/5719943 to your computer and use it in GitHub Desktop.
Celluloid application from https://speakerdeck.com/therealadam/big-ruby-conf-bonus-tracks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'socket' | |
socket = TCPSocket.open('localhost', 3000) | |
socket.write("STATS /") | |
puts socket.read | |
socket.close |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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