C言語で XML-RPC をしゃべる為のライブラリ libxmlrpc-c を使った非同期問い合わせについて。
また例のどう書く?ネタなんだけど、XML-RPC リクエストを大量に行う場合、シリアルに問い合わせを行うと、どうにもならないくらい遅かったので非同期問い合わせに書き直してみた。
libxmlrpc-c にはサーバーに同期的にブロックして問い合わせる関数 xmlrpc_client_call() の他に非同期で問い合わせを行う xmlrpc_client_call_asynch() が用意されている。
この非同期関数のサンプルコードをマネマネして書いてみたんだけど一向にパフォーマンスが向上しないので調べてみると、xmlrpc_client_call_asynch() の関数自体はノンブロッキングで帰ってきているが、実際の XML-RPC リクエストは 1っ発づつ送られていることが解った。
あれこれパラメーターを変えたりしてずいぶん悩まされた結果、答えはドキュメントに書いてあった。
http://xmlrpc-c.sourceforge.net/doc/libxmlrpc_client.html#concurrency_libwww
より
The asynchronous facility, in at least one experiment Bryan did, was rather disappointing used with the libwww transport. The no-wait call had no visible effect, and the RPC finishing function did each RPC serially (waits for one to complete before starting the next one). Because libwww is undocumented and its code too complex to read easily, Bryan did not determine if there are circumstances under which it behaves better.
libxmlrpc-c は transport(HTTP リクエストを送るレイヤのライブラリ)として、libwww と libcurl をサポートしているんだけど、デフォルトで使用される libwww の場合、非同期問い合わせは絶望的なんだそうな。libwww はアンドキュメンテッドな上コードが複雑すぎて非同期問い合わせに対応できなかったんだそうな。
で、debian package の libxmlrpc-c3 には libcurl の transport が組み込まれていなかったので、libxmlrpc-c-1.06.17 のソースをダウンロードしてきてコンパイルしようとすると
% ./configure —-disable-libwww-client
% make
gcc -o xmlrpc xmlrpc.o dumpvalue.o blddir/lib/util/cmdline_parser.o blddir/lib/util/getoptx.o blddir/lib/util/casprintf.o -Lblddir/src/.libs -lxmlrpc_client -lxmlrpc -L/usr/lib -lcurl -L/usr/lib -lgssapi_krb5 -lkrb5 -lk5crypto -lkrb5support -lcom_err -lresolv -lidn -lssl -lcrypto -ldl -lssl -lcrypto -lz -Lblddir/lib/expat/xmlparse/.libs -lxmlrpc_xmlparse -Lblddir/lib/expat/xmltok/.libs -lxmlrpc_xmltok -Lblddir/lib/libutil/.libs -lxmlrpc_util
blddir/src/.libs/libxmlrpc.so: undefined reference to `xmlCreatePushParserCtxt’
blddir/src/.libs/libxmlrpc_client.so: undefined reference to `xmlrpc_libwww_transport_ops’
blddir/src/.libs/libxmlrpc.so: undefined reference to `xmlParseChunk’
blddir/src/.libs/libxmlrpc.so: undefined reference to `xmlFreeParserCtxt’
collect2: ld returned 1 exit status
エラー。
expat の問題っぽいので試しに、XML パーサーを libxml に変えてみる
% ./configure —-disable-libwww-client —-enable-libxml2-backend
% make
gcc -o xmlrpc xmlrpc.o dumpvalue.o blddir/lib/util/cmdline_parser.o blddir/lib/util/getoptx.o blddir/lib/util/casprintf.o -Lblddir/src/.libs -lxmlrpc_client -lxmlrpc -L/usr/lib -lcurl -L/usr/lib -lgssapi_krb5 -lkrb5 -lk5crypto -lkrb5support -lcom_err -lresolv -lidn -lssl -lcrypto -ldl -lssl -lcrypto -lz -L/usr/lib -lxml2 -lz -lpthread -lm -Lblddir/lib/libutil/.libs -lxmlrpc_util
blddir/src/.libs/libxmlrpc_client.so: undefined reference to `xmlrpc_libwww_transport_ops’
collect2: ld returned 1 exit status
今度は違うエラー、眠い、xmlrpc というと XML-RPC リクエストをお手軽に問い合わせることが出来る便利ツールだったはず。debian package に含まれていない理由はこんなところかな。
configure を追っかけて tools/xmlrpc をビルドしないようにするためには —-disable-cplusplus を付ければよいことが解った。(tools/xmlrpc は C++じゃないのに!)
% ./configure —-disable-libwww-client —-enable-libxml2-backend —-disable-cplusplus
% make
この様にしてビルドした libxmlrpc-c で無事非同期問い合わせが出来ましたとさ。Happy!
Robert wrote related post…
Silk posts and stories…
Trackback by Robert wrote related post — 2008/06/19 Thursday @ 22:01:57