Craftworks Tech Blog - Branch このページをアンテナに追加 RSSフィード

2010-11-04

WWW::Curl で使えるオプション一覧

| 01:43 |  WWW::Curl で使えるオプション一覧 - Craftworks Tech Blog - Branch を含むブックマーク  WWW::Curl で使えるオプション一覧 - Craftworks Tech Blog - Branch のブックマークコメント

WWW::Curl は速いですがドキュメントが少ないのが玉に瑕です。perldoc に setopt() や getinfo() で指定できるオプション一覧が載っていないです。

実は PHPマニュアルに良い感じで載っています。

setopt() に指定できるオプション一覧

getinfo() に指定できるオプション一覧

[追記]

tokuhirom 氏から公式情報の URL を頂きました。ありがとうございます!

http://curl.haxx.se/libcurl/c/curl_easy_setopt.html

http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html

tokuhiromtokuhirom 2010/11/05 11:29 そこ日本語なのはいいんですが、最新版には追随していないかもしれません。

最新のオプションのデータは一時情報をみるとよいかとおもいました
http://curl.haxx.se/libcurl/c/curl_easy_setopt.html
http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html

2009-09-07

Tokyo Tyrant 用テストモジュール Test::ttserver リリース

| 02:58 | Tokyo Tyrant 用テストモジュール Test::ttserver リリース - Craftworks Tech Blog - Branch を含むブックマーク Tokyo Tyrant 用テストモジュール Test::ttserver リリース - Craftworks Tech Blog - Branch のブックマークコメント

Key Value Store の Tokyo Cabinetデータベースサーバーである、Tokyo Tyrantインスタンス起動管理サーバーttserver をテスト用に一時的に起動できる Test::ttserver をリリースしました。

http://search.cpan.org/~craftwork/Test-ttserver-0.001/lib/Test/ttserver.pm

現在、Engage という WAF を開発しているのですが、その中のデータアクセス抽象化クラスで Tokyo Tyrant を使うことにしたところ、テストを書く段階で、「ttserver を立ち上げないとテストが出来ないなぁ」と思い作りました。

実装は奥氏の Test::mysqld をベースに、ttserver 用に書き換えました。id:kazuhooku++

これが CPAN Author デビューになるので、先人の方々のツッコミをお待ちしております。

2009-09-06

Test::Dependencies と Module::Install でテストが通らない

| 23:24 | Test::Dependencies と Module::Install でテストが通らない - Craftworks Tech Blog - Branch を含むブックマーク Test::Dependencies と Module::Install でテストが通らない - Craftworks Tech Blog - Branch のブックマークコメント

依存モジュールの指定漏れを防ぐ方法 - 名称未設定 - subtech

Makefile.PL に書き忘れている依存モジュールを自動検出してくれるテストモジュール Test::Dependencies ですが、Module::Install と併用していると、テストがコケます。

これは、Module::Install が生成する META.yml の中に、

build_requires:
  ExtUtils::MakeMaker: 6.42

が書いてあるのに関わらず、どのテストスクリプトにも、use ExtUtils::MakeMaker が無いのが原因です。

META.yml の中の ExtUtils::MakeMaker の記述を消せば、テストは通るのですが、自動生成されるファイルをいちいち編集するのも面倒ですし、そもそも Module::Install が、わざわざバージョン指定しているので、消すことによって何か不具合が起こりそうですし、解決策としてはやっつけ過ぎです。

他の CPAN モジュールはどうしているのかなと思い、いくつか同梱の META.yml を覗いてみましたが、build_requires に ExtUtils::MakeMaker を指定していないモジュール結構ありました。

結局、どうしたら良い解決法なのか分かりませんが、とりあえず、下記のように Test::Dependencies を使っているテストスクリプトに、use ExtUtils::MakeMaker を書いて誤魔化すことにしました。

use ExtUtils::MakeMaker;
use Test::Dependencies
    exclude => [qw/Test::Dependencies MyModule/],
    style   => 'light' ;

ok_dependencies();

皆さんはどう対処されているでしょうか?

2009-09-01

例外捕捉モジュール Try::Tiny のベンチマーク

| 16:40 | 例外捕捉モジュール Try::Tiny のベンチマーク - Craftworks Tech Blog - Branch を含むブックマーク 例外捕捉モジュール Try::Tiny のベンチマーク - Craftworks Tech Blog - Branch のブックマークコメント

Yuval Kogman 氏が Try::Tiny という新しい例外捕捉モジュールリリースしたようなので、ベンチマークを取ってみました。

ベンチマークコードは、Error.pm のオーバーヘッドで書いたものを流用しました。

ベンチマークコード

#!/usr/bin/perl
use strict;
use warnings;
use Benchmark qw(:all);
use Try::Tiny;
use Error;

cmpthese(timethese(100000, {
    'eval' => sub {
        _eval(\&die_with_object);
        _eval(\&die_with_string);
        _eval(\&dont_die);
    },
    'try'  => sub {
        _tiny(\&die_with_object);
        _tiny(\&die_with_string);
        _tiny(\&dont_die);
    },
}));

sub die_with_object {
    Error::Simple->throw('object');
}

sub die_with_string {
    die 'string';
}

sub dont_die {
    return "still alive\n";
}

sub _eval {
    my $code = shift;
    my $res;
    eval {
        $res = $code->();
    };
    if (ref $@ eq 'Error::Simple') {
        $res = $@->stacktrace;
    }
    elsif ($@) {
        $res = $@;
    }
    return $res;
}


sub _tiny {
    my $code = shift;
    my $res;
    try {
        $res = $code->();
    }
    catch {
        if (ref $@ eq 'Error::Simple') {
            $res = $@->stacktrace;
        }
        elsif ($@) {
            $res = $@;
        }
    };
    return $res;
}

ベンチマーク結果

Benchmark: timing 100000 iterations of eval, try...
      eval: 11 wallclock secs (10.52 usr +  0.00 sys = 10.52 CPU) @ 9505.70/s (n=100000)
       try: 19 wallclock secs (18.57 usr +  0.01 sys = 18.58 CPU) @ 5382.13/s (n=100000)
       Rate  try eval
try  5382/s   -- -43%
eval 9506/s  77%   --

結論

Error より速いですが、オブジェクトごとに with で補足したりはできないので、やはり eval と if で良い気がします。

2009-07-18

一番近い CPAN ミラーを検出するスクリプトを書いた

| 17:22 | 一番近い CPAN ミラーを検出するスクリプトを書いた - Craftworks Tech Blog - Branch を含むブックマーク 一番近い CPAN ミラーを検出するスクリプトを書いた - Craftworks Tech Blog - Branch のブックマークコメント

READ IN ENGLISH

CPAN モジュールをインストールするときに、ダウンロード速度が気になったので、ミラーサイトから一番近いサイトをピックアップするスクリプトを書いてみました。

CPAN から、MIRRORED.BY を取ってきて、dst_http に指定されているホスト全てに、5回 ping を飛ばして、平均スピードが速かった上位 5 サイトの URI を出力します。o conf ラインも出力するので、cpan シェルにそのままコピペで設定できます。o conf commit を忘れないように注意。

ftp を使いたい人は、dst_http を dst_ftp に変更してください。

ちなみに、EC2 の us-east-1c からは、以下のサイトがランクインしました。

2.311 ms : cpan-du.viaverio.com
7.732 ms : ftp.fxcorporate.com
8.229 ms : mirrors.24-7-solutions.net
8.912 ms : mirror.datapipe.net
9.388 ms : mirror.cc.columbia.edu
o conf urllist push http://cpan-du.viaverio.com/
o conf urllist push http://ftp.fxcorporate.com/CPAN/
o conf urllist push http://mirrors.24-7-solutions.net/pub/CPAN/
o conf urllist push http://mirror.datapipe.net/CPAN/
o conf urllist push http://mirror.cc.columbia.edu/pub/software/cpan/
o conf commit

以下ソースです。

#!/usr/bin/perl
use strict;
use warnings;
use IPC::Open2;
use LWP::Simple;

my $mirrored_by = 'http://www.cpan.org/pub/CPAN/MIRRORED.BY';

my $content = get( $mirrored_by );
die "Couldn't get MIRRORED.BY" unless defined $content;

my $data;
for my $uri ( $content =~ /^\s+dst_http\s+=\s+"(.+?)"/gm ) {

    my $host = URI->new( $uri )->host;
    printf "%-40s\r", $host;

    open2( my $out, undef, qw(ping -nq -c 5 -i 0.2), $host );
    my @res = <$out>;
    $out->close;

    my ( $loss ) = $res[-2] =~ /(\d)% packet loss/o;
    my ( $avg  ) = (split '/', $res[-1])[4];
    next if $loss ne '0';
    next if !$avg;

    $data->{$host} = {
        uri => $uri,
        avg => $avg,
    };
}

my @rank = sort { $data->{$a}{'avg'} <=> $data->{$b}{'avg'} } keys %$data;

my ( $rank, $conf ) = ('') x 2;
for my $host (@rank[0..4]) {
    $rank .= sprintf "%s ms : %s\n", $data->{$host}{'avg'}, $host;
    $conf .= sprintf "o conf urllist push %s\n", $data->{$host}{'uri'};
}
print " " x 50, "\n";
print $rank, $conf;
print "o conf commit\n";