Working with TCP Sockets 読書メモ 目次
スレッドプール
- このパターンは、preforkのスレッド版
実装
require 'socket'
require 'thread'
require_relative 'command_handler'
module FTP
Connection = Struct.new(:client) do
CRLF = "\r\n"
def gets
client.gets(CRLF)
end
def respond(message)
client.write(message)
client.message(CRLF)
end
def close
client.close
end
end
class ThreadPool
CONCURRENCY = 25
def initialize(port = 21)
@control_socket = TCPServer.new(port)
trap(:INT) { exit }
end
def run
Thread.abort_on_exception = true
threads = ThreadGroup.new
CONCURRENCY.times do
threads.add spawn_thread
end
sleep # 終了しないようにする
end
def spawn_child
Thread.new do
loop do
conn = Connection.new(@control_socket.accept)
conn.respond "220 OHAI"
handler = CommandHandler.new(conn)
loop do
request = conn.gets
if request
conn.respond handler.handle(request)
else
conn.close
break
end
end
end
end
end
end
end
server = FTP::ThreadPool.new(4481)
server.run
ThreadGroup
に含まれるスレッドが実行終了すると、ThreadGroup
はスレッドをグループ内から削除する