Working with TCP Sockets 読書メモ 第20章 スレッドプール

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はスレッドをグループ内から削除する

コメントを残す

コメントを残す