gunicornのWorkerを書いてみた

gunicornはWorkerクラスを差し替えられるので少し調べてた。
gunicorn.workers.sync.SyncWorker を継承してechoサーバのWorkerを書いてみた。

# coding: utf-8                                                                                                                                                                                
# echo_worker.py

import errno
import socket

from gunicorn import util
from gunicorn.workers import sync

READ_BLOCK_SIZE = 1024

class SyncEchoWorker(sync.SyncWorker):
    def handle(self, client, addr):
        try:
            self.handle_echo(client, addr)
        except StopIteration:
            self.log.debug("Ignored premature client disconnection.")
        except socket.error, e:
            if e[0] != errno.EPIPE:
                self.log.exception("Error processing request.")
            else:
                self.log.debug("Ignoring EPIPE")
        except Exception, e:
            self.handle_error(client, e)
        finally:
            util.close(client)

    def handle_echo(self, client, addr):
        buf = ''
        while True:
            data = client.recv(READ_BLOCK_SIZE)
            buf += data
            while True:
                # 改行コードがあれば出力する
                if '\n' in buf:
                    out, buf = data.split('\n', 1)
                else:
                    break
                client.send(out + '\n')


def application(envrion, start_response):
    pass

このコードだとコネクションが切れるまでぐるぐるやってるので、プロセスの数しか処理できないです。
まあ練習ってことで。
起動のコマンドはこんな感じ。

$ gunicorn --worker-class=echo_worker.SyncEchoWorker echo_worker:application -w 4 -t 180

動作を試すにはtelnetから接続。

$ telnet localhost 8000