読者です 読者をやめる 読者になる 読者になる

Keep on moving

あんまりまとまってないことを書きますよ

pyuvと戯れる

python network libuv

どうも今晩は。よく本業が何かと聞かれますが、自分でもたまに本業がなにかよくわからなくなります。

最初に

近頃サーバーサイドJavaScriptのnode.jsの人気が出てますね。
node.jsの作者が作ってるネットワーク用のライブラリlibuvはgeventの裏側でつかわれているlibev風のAPI
Windowsでも使えるという話を聞いて楽しそうなので触ってみました。

しかし、ドキュメントもほとんどなく、近頃Cから始まる言語を使っていない私には少々敷居が高いこともあり
Pythonでwrapしているものを探してみました。

最悪の場合、気分転換にpython版を書いてみるかと思ったのですが、既に書いてる人がいました。
しかもほとんどの機能をPythonから使えるようにwrap済みです、これはありがたい。というわけで今回はこれを使ってみます。

https://github.com/saghul/pyuv

導入

Pypiでの公開はされてないみたいです。
githubで公開されてますのでgitで取ってきます。

$ git clone https://github.com/saghul/pyuv.git

その後、setup.py を使ってbuild/install します。

$ python setup.py build
$ sudo python setup.py install

TCPのEchoサーバー動かしてみる。
例によって写経ですよ。 https://github.com/saghul/pyuv/blob/master/examples/echo-server-tcp.py

import os
import signal
import threading
import pyuv

def on_client_shutdown(client):
    client.close()
    clients.remove(client)

def on_read(client, data):
    if data is None:
        client.close()
        clients.remove(client)
        return
    data = data.strip()
    if not data:
        return
    client.write(data+os.linesep)
    client.shutdown(on_client_shutdown)

def on_connection(server):
    client = server.accept()
    clients.append(client)
    client.start_read(on_read)

def async_exit(async):
    [c.close() for c in clients]
    async.close()
    signal_h.close()
    server.close()

def signal_cb(sig, frame):
    async.send(async_exit)


print "PyUV version %s" % pyuv.__version__

loop = pyuv.Loop()

async = pyuv.Async(loop)
clients = []

server = pyuv.TCP(loop)
server.bind(("0.0.0.0", 5000))
server.listen(on_connection)

signal_h = pyuv.Signal(loop)
signal_h.start()

t = threading.Thread(target=loop.run)
t.start()

signal.signal(signal.SIGINT, signal_cb)
signal.pause()

t.join()

print "Stopped!"

速度

DSAS開発者の部屋:最速TCPサーバーの条件 〜逆襲の Erlang と Haskell の挑戦〜を参考に速度比較を取ってみました
※ VMでの実行結果なので実マシンの場合はかわるかも
※ サーバーとクライアントを同じVMで実行しているので計測の仕方はあまりよくないです。
※ 4core 1024M の環境で計測

f:id:Ehren:20111226005432p:image
詳細はここ

Tornadoと比べると多少遅いくらいで動作するみたいですね。Loopさせているところも含めて設計もわりと近いイメージですね。

参考

現状ドキュメントはない?ヘッダを読むしかないのかな

Python/C API リファレンスマニュアル — Python 2.7ja1 documentation

まとめ

libuv自体がまだ、リリースバージョンがついてないだけに今後どうなるかわかりませんが、
いろいろ遊べそうです。
あ、そうそう本家のlibuvはwindows対応を行ってますが、pyuvはまだwindowsでの動作確認がきちんと
行われていないようです。