pyuvと戯れる
どうも今晩は。よく本業が何かと聞かれますが、自分でもたまに本業がなにかよくわからなくなります。
最初に
近頃サーバーサイドJavaScriptのnode.jsの人気が出てますね。
node.jsの作者が作ってるネットワーク用のライブラリlibuvはgeventの裏側でつかわれているlibev風のAPIを
Windowsでも使えるという話を聞いて楽しそうなので触ってみました。
しかし、ドキュメントもほとんどなく、近頃Cから始まる言語を使っていない私には少々敷居が高いこともあり
Pythonでwrapしているものを探してみました。
最悪の場合、気分転換にpython版を書いてみるかと思ったのですが、既に書いてる人がいました。
しかもほとんどの機能をPythonから使えるようにwrap済みです、これはありがたい。というわけで今回はこれを使ってみます。
導入
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 の環境で計測
Tornadoと比べると多少遅いくらいで動作するみたいですね。Loopさせているところも含めて設計もわりと近いイメージですね。
まとめ
libuv自体がまだ、リリースバージョンがついてないだけに今後どうなるかわかりませんが、
いろいろ遊べそうです。
あ、そうそう本家のlibuvはwindows対応を行ってますが、pyuvはまだwindowsでの動作確認がきちんと
行われていないようです。