Doge log

Abby CTO 雑賀 力王のオフィシャルサイトです

pyeventでecho

ノンブロッキングのサンプル

import event
import socket
import errno
import signal


def _read(sock):
  try:
    return sock.recv(1024)
  except socket.error, e:
    if e[0] == errno.EWOULDBLOCK:
      return None
    raise
  
def start_client(sock):
  res = _read(sock)
  if res:
    sock.send(res)
    sock.close()
    print("close")
  else:
    print("regist read %d" % sock.fileno())
    event.read(sock, start_client, sock)

def _accept(sock):
  try:
    return sock.accept()
  except socket.error, e:
    if e[0] == errno.EWOULDBLOCK:
        return None
    raise

def accept(sock):
  res = _accept(sock)
  if res:
    conn, addr = res
    conn.setblocking(0)
    start_client(conn)
    accept(sock)
  else:
    print("regist accept %d" % sock.fileno())
    event.read(sock, accept, sock)

server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_sock.bind(('localhost' , 6000))
server_sock.listen(10)
#non blocking
server_sock.setblocking(0)

def stop(sig):
  print("stop")
  event.abort()
  raise KeyboardInterrupt()

event.signal(signal.SIGINT, stop, signal.SIGINT).add()

accept(server_sock)
event.dispatch()

自作でmainloopを作ってやるタイプがなぜかうまくいかない....
変なところでブロックしたり、signalを仕込む、仕込まないでちょっと挙動が変ったりするので怪しい。

libevでもちょっとやってるけどacceptでうまく止まってくれない。
バックエンドがselectになってるのかも知れない。
そもそもドキュメント読めって話だと思うが。

並列度をあげるために色々やるのはいいけどスレッド(プロセス)内で再度読み込み(recv)をさせるなど
すると難しくなるので注意。