2010年03月09日

トランザクションを使用したMySQLのおまとめINSERTはどれくらい速いか

元ネタはMySQL のおまとめINSERTはどれくらい速いか - bonar noteです。

トランザクションでまとめてInsertしてからcommitしたほうが速くなるので、元ネタのベンチマークをベースにして試してみました。

環境は macports で入れた mysql 5.1.44 です。

まぁnormalからbulk(100)くらいの差は出てなくても、トランザクション使ってまとめてコミットしても多少速くなっとりますね。
normal と txn の差よりも bulk(100) と bulk(100)_txn の差が小さいのは、 bulk insert で最初から効率的になってるぶん差が少なくなってるという感じでしょうか。

コードは以下の通り。

Posted by Yappo at 12:35 | Comments (0) | TrackBack

2009年11月11日

Go lang (golang) に Acme::Oppai を移植してみた

取りあえずどんな感じでライブラリ書けるか見る為に Acme::Oppai を移植してみた訳です。
メソッドチェインしてAAが腕を上下してる感じは出来ました。
Go言語は組み込みでライブラリ書く仕組みが一通り整備されてる感じぽいすねContributing to the Go projectにテストの書き方まで書いてあった。
acme/oppai も一応テスト書いてあります。
普通に make && make test && make install してインストール出来るので、あとは貴方のコードからおっぱいおっぱい言うAAを取り扱う事が出来ます。

コードは http://github.com/yappo/Go-acme-oppai
これを使ったコードは以下の通りです。

メソッドチェインの終わりを知る方法がいまいちわからなくてDoneメソッドを呼ぶようにしてあります。
Perlだと""でoverloadさせて、オブジェクトが文字列評価された時に一気にAAを返したり出来たんですけどね。
あと、あんまドキュメント読んでないんですが大文字で始まるメソッドじゃないとpublic methodにならない?

とりあえずgistのGo対応はまだか?

Posted by Yappo at 21:21 | Comments (0) | TrackBack

2009年06月30日

MyISAM/InnoDB で primary key/index/uniqu な複合カラムなインデックス貼って SELECT COUNT(*) FROM table WHERE column = x したベンチマーク

とってみた物の、どれも速度変わらんっぽいなぁ。計りかたわるいかなぁ。

結果は下記の通り
先頭の文字が l = InnoDB, h = MyISAM, 二番目の数字や、最後の文字の意味はベンチスクリプト見てくださいなり。

一応適すとでもこぴえp

[~/perl]$ perl ./sql-count-benchmark.pl
^[[C        Rate l4_i l3_i h2_n l3_n l2_i l4_n h3_n h4_n h1_i l1_n h3_i l1_i h4_i h1_n l2_n h2_i
l4_i 10638/s   --  -3%  -5%  -6%  -7% -10% -10% -11% -12% -13% -14% -14% -16% -17% -18% -18%
l3_i 10989/s   3%   --  -2%  -3%  -4%  -7%  -7%  -8%  -9% -10% -11% -11% -13% -14% -15% -15%
h2_n 11236/s   6%   2%   --  -1%  -2%  -4%  -4%  -6%  -7%  -8%  -9%  -9% -11% -12% -13% -13%
l3_n 11364/s   7%   3%   1%   --  -1%  -3%  -3%  -5%  -6%  -7%  -8%  -8% -10% -11% -12% -12%
l2_i 11494/s   8%   5%   2%   1%   --  -2%  -2%  -3%  -5%  -6%  -7%  -7%  -9% -10% -11% -11%
l4_n 11765/s  11%   7%   5%   4%   2%   --  -0%  -1%  -2%  -4%  -5%  -5%  -7%  -8%  -9%  -9%
h3_n 11765/s  11%   7%   5%   4%   2%   0%   --  -1%  -2%  -4%  -5%  -5%  -7%  -8%  -9%  -9%
h4_n 11905/s  12%   8%   6%   5%   4%   1%   1%   --  -1%  -2%  -4%  -4%  -6%  -7%  -8%  -8%
h1_i 12048/s  13%  10%   7%   6%   5%   2%   2%   1%   --  -1%  -2%  -2%  -5%  -6%  -7%  -7%
l1_n 12195/s  15%  11%   9%   7%   6%   4%   4%   2%   1%   --  -1%  -1%  -4%  -5%  -6%  -6%
h3_i 12346/s  16%  12%  10%   9%   7%   5%   5%   4%   2%   1%   --   0%  -2%  -4%  -5%  -5%
l1_i 12346/s  16%  12%  10%   9%   7%   5%   5%   4%   2%   1%   0%   --  -2%  -4%  -5%  -5%
h4_i 12658/s  19%  15%  13%  11%  10%   8%   8%   6%   5%   4%   3%   3%   --  -1%  -3%  -3%
h1_n 12821/s  21%  17%  14%  13%  12%   9%   9%   8%   6%   5%   4%   4%   1%   --  -1%  -1%
l2_n 12987/s  22%  18%  16%  14%  13%  10%  10%   9%   8%   6%   5%   5%   3%   1%   --  -0%
h2_i 12987/s  22%  18%  16%  14%  13%  10%  10%   9%   8%   6%   5%   5%   3%   1%   0%   --
[~/perl]$ perl ./sql-count-benchmark.pl
        Rate l3_i l4_n l3_n h4_n l4_i h4_i l2_n l2_i h2_n h2_i h1_i h3_i h3_n l1_i h1_n l1_n
l3_i 10753/s   --  -1%  -3%  -3%  -6%  -9% -10% -11% -11% -11% -11% -13% -14% -15% -16% -18%
l4_n 10870/s   1%   --  -2%  -2%  -5%  -8%  -9% -10% -10% -10% -10% -12% -13% -14% -15% -17%
l3_n 11111/s   3%   2%   --  -0%  -3%  -6%  -7%  -8%  -8%  -8%  -8% -10% -11% -12% -13% -16%
h4_n 11111/s   3%   2%   0%   --  -3%  -6%  -7%  -8%  -8%  -8%  -8% -10% -11% -12% -13% -16%
l4_i 11494/s   7%   6%   3%   3%   --  -2%  -3%  -5%  -5%  -5%  -5%  -7%  -8%  -9% -10% -13%
h4_i 11765/s   9%   8%   6%   6%   2%   --  -1%  -2%  -2%  -2%  -2%  -5%  -6%  -7%  -8% -11%
l2_n 11905/s  11%  10%   7%   7%   4%   1%   --  -1%  -1%  -1%  -1%  -4%  -5%  -6%  -7% -10%
l2_i 12048/s  12%  11%   8%   8%   5%   2%   1%   --   0%  -0%  -0%  -2%  -4%  -5%  -6%  -8%
h2_n 12048/s  12%  11%   8%   8%   5%   2%   1%   0%   --  -0%  -0%  -2%  -4%  -5%  -6%  -8%
h2_i 12048/s  12%  11%   8%   8%   5%   2%   1%   0%   0%   --   0%  -2%  -4%  -5%  -6%  -8%
h1_i 12048/s  12%  11%   8%   8%   5%   2%   1%   0%   0%   0%   --  -2%  -4%  -5%  -6%  -8%
h3_i 12346/s  15%  14%  11%  11%   7%   5%   4%   2%   2%   2%   2%   --  -1%  -2%  -4%  -6%
h3_n 12500/s  16%  15%  13%  13%   9%   6%   5%   4%   4%   4%   4%   1%   --  -1%  -2%  -5%
l1_i 12658/s  18%  16%  14%  14%  10%   8%   6%   5%   5%   5%   5%   3%   1%   --  -1%  -4%
h1_n 12821/s  19%  18%  15%  15%  12%   9%   8%   6%   6%   6%   6%   4%   3%   1%   --  -3%
l1_n 13158/s  22%  21%  18%  18%  14%  12%  11%   9%   9%   9%   9%   7%   5%   4%   3%   --
<

Server version: 5.1.33 Source distribution
use strict;
use warnings;
use DBI;

use Benchmark ':all';

my $dbh = DBI->connect('DBI:mysql:test');
sub setup {
    for (1..4) {
        $dbh->do("DROP TABLE IF EXISTS hatena$_");
        $dbh->do("DROP TABLE IF EXISTS labs$_");
    }

    $dbh->do(q{
CREATE TABLE hatena1 (
    id    int unsigned,
    name  char(10),
    primary key(id, name),
    index(name, id)
) TYPE=MyISAM
});
    $dbh->do(q{
CREATE TABLE hatena2 (
    id    char(10),
    name  char(10),
    primary key(id, name),
    index(name, id)
) TYPE=MyISAM
});
    $dbh->do(q{
CREATE TABLE hatena3 (
    id    char(10),
    name  char(10),
    unique(id, name),
    index(name, id)
) TYPE=MyISAM
});
    $dbh->do(q{
CREATE TABLE hatena4 (
    id    char(10),
    name  char(10),
    index(id, name),
    index(name, id)
) TYPE=MyISAM
});

    $dbh->do(q{
CREATE TABLE labs1 (
    id    int unsigned,
    name  char(10),
    primary key(id, name),
    index(name, id)
) TYPE=InnoDB
});
    $dbh->do(q{
CREATE TABLE labs2 (
    id    char(10),
    name  char(10),
    primary key(id, name),
    index(name, id)
) TYPE=InnoDB
});
    $dbh->do(q{
CREATE TABLE labs3 (
    id    char(10),
    name  char(10),
    unique(id, name),
    index(name, id)
) TYPE=InnoDB
});
    $dbh->do(q{
CREATE TABLE labs4 (
    id    char(10),
    name  char(10),
    index(id, name),
    index(name, id)
) TYPE=InnoDB
});
}
setup if $ARGV[0]||'' eq 'setup';

sub apply_insert {
    my @buf = @_;
    for my $num (1..4) {
        for my $name (qw/ hatena labs /) {
            $dbh->do(sprintf "INSERT INTO $name$num (id, name) VALUES%s;", join(', ', @buf));
        }
    }
}

if ($ARGV[0]||'' eq 'setup') {
    my @buf;
    for my $id (1..1000) {
        for my $name (1..1000) {
            push @buf, "($id, $name)";
            if (@buf == 1000) {
                apply_insert(@buf);
                @buf = ();
            }
        }
    }
    if (@buf) {
        apply_insert(@buf);
    }
}

my $coderefs = {};
my $countcache = {};
for my $name (qw/ hatena labs /) {
    for my $num (1..4) {
        my $table = "$name$num";
        for my $column (qw/ id name /) {
            my $testname = join '', substr($name, 0, 1), $num, '_', substr($column, 0, 1);
            $coderefs->{$testname} = sub {
                my $sth = $dbh->prepare("SELECT COUNT(*) FROM $table WHERE $column = ?");
                $countcache->{$testname}++;
                $sth->execute($countcache->{$testname} % 1000);
            };
        }
    }
}

cmpthese( 10000 => $coderefs);

という生魚的エントリ。

Posted by Yappo at 15:48 | Comments (0) | TrackBack

2009年05月19日

yacc と lex で簡易言語の AcotieScript っての作ってみた

そろそろ梅雨入りするので急いでキュウリの苗植えたら安物のせいか根っこが弱っこくて少し心配な金曜日担当Yappoです。

Perlも飽きたし、ふと思う所があって、オレオレ言語を作ってみました。
http://github.com/yappo/AcotieScript/tree/master
たぶんMacでしか動かないんじゃないかなとは思ってますが、普通にmakeすればコンパイルされる筈。

サポートされているシンタックスはコメントとprintとperlにあるような文字列同士のxorです。

"hoge" ^ "ugee"
みたいのですが、これを実行すると死にます。元ネタの人が文字列xorを理解したら正しく動くなる予定です。

printは

print "hello\n"
を実行すると「おうっふー hello」とprefixにおうっふーを追加します。

AcotieScriptの最大の特徴は、コメント構文の豊富さで、次の物は全てコメントとして解釈されます。

//this is comment
#this is comment
/*this is comment*/
"""this is comment
'''this is comment
<!--this is comment-->
REM this is comment
また、実行文の後ろにも次の物はコメントになります。
    print "hello!\n" #    this is comment
    print "hello!\n" //   this is comment
    print "hello!\n" """  this is comment
    print "hello!\n" '''  this is comment
    print "hello!\n" :REM this is comment

その他構文は{}のブロックはサポートしているが意味ありません。
またrubyの用っぽく1行で1つの文になり、一つの行に複数の文を置きたければ;で区切れます。

print "hoge\n" # 1文
print "foo\n";print "bar\n" # 2文

サポートされているリテラルは文字列リテラルのみでシングルクオートとダブルクオートが使えます。
それぞれはだいたいその他の言語のような動きはします。

コマンドラインでもいけます

acotiescript -e 'print "hello\n"'

shebang使えます。

$ cat oufu.acotie 
#!./acotiescript

print "うっ!\n"
$ ./oufu.acotie 
おうっふー うっ!

今後

今のままだと100% CGIとして動作しないので、CGIとして動作するようにするかも。
構文解析した物をスタック詰んだりしないで、逐一実行するだだからifやらwhileやら作るの面倒いのでスタック型にするかなーとか
mod_acotie作ってみるのはどうか?

まとめ

perlとrubyはparserをyaccでやってトークナイザはlex使わないで自前でやってる。
PHPもyacc使ってるが何かスッゲーきたない。
Pythonは全部自前でやっててコンパクトでシンプルでソース量も少なかった。

とりあえずlex使うと楽ですね。yaccは規則がループしたりしないようにするように作らないといけないのだが、気を抜くと循環参照しだしてパースが終わんなくなる。
perl -e 'print "hello"' みたいな -e オプションを実装するのにfunopenを使って、文字列バッファをstdioインターフェィスに組み込めるような機能を関数を使ったがBSDでしか使えなっぽ。
perlとかだとトークナイザは自前なのでどうとでもなるが、lex使うとFILE *なものしかやってくれないので、char *をFILE *にしてくれる汎用的な方法ないかなーと探してる所。

あとコマンドラインオプション解析は getopt を使いました。 argv[1] がファイル名だったらそれスキップします。

そんな感じでfork歓迎push requestも歓迎です!

Posted by Yappo at 11:24 | Comments (0) | TrackBack

2009年04月16日

はてなのお気に入りアンテナをTwitter Clientで見れるゲートウェイ「Hatetter」作りました

注意:ブックマークだけでなく、お気に入りアンテナのフィードを使うようになりました。

はてブのお気に入りリストってRSSリーダとかで見たりするのが多いんですが、もっとTwitterのようにカジュアルにウオッチしたいと思って、お気に入りリストのRSSをTwitter API互換のFeedに変換するサーバを書きました。

Hatter - 太っ腹にソースコードも公開してるので、自宅サーバとかに置いて使うってのもできます。

たとえばid:acotieがお気に入りに入れてる人達のブックマークをTwitter風に変換したい時は

http://hatetter.blogdb.jp/acotie/statuses/friends_timeline.json
もしくは
http://hatetter.blogdb.jp/acotie/statuses/friends_timeline.xml
を使います。一回目アクセスした時は空ですが、1分くらい立つとFeedが出来てきます。
このままだとXMLやらJSONがそのまま出てくるので、何かしら専用くらいんとから見ると良いです。

XMLとJSONに変換するので、たいがいのクライアントで見れるようになるんじゃないかなぁと期待しています。

技術的補足

Hatterでは、Perl以外にもQ4Mとmemcachedを使っています。

最初リクエストがあった時には、空の結果を返しつつQ4Mにキューを詰んで、数十秒後にQ4MのWorkerがFeedを取りに行って、Feedの変換を行い、結果をmemcachedに積み込んでいます。
で、クライアントからの二度目のアクセスの時にはmemcachedに入っている変換結果を出すだけです。
一度キューに突っ込んだらmemcachedに時間を保存しておいて5分以内は、キューに突っ込まれないようにしています。
と言った事を、一つのID毎に行っているので大量のアクセスが来たとしても自分のサーバも、はてなのサーバも大変な事にならない予定です。
Webアプリとしてはmemcachedとmysql(Q4M)との間でしか通信しないので、殆どブロックする事無く高速に応答出来るのではないかと思っています。
また、大量に使われる事になってキューがいっぱいたまってもQ4MなのでFeedの処理で過負荷になることも無くて安心です。やばければworkerのプロセス増やせば良いだけですしね。

キューに関しても3回retryして失敗したらキューを捨てるという事をやっていて、これもData::Model::Driver::Queue::Q4Mのお陰で簡潔に実装が行われています。
Queue::Q4Mとは違って、queue_waitに渡すテーブルに対するコールバックハンドラを渡す感じになっていたり、queue_endやqueue_abortの面倒見なくても良い、また対応するqueueのレコードを予め取得してobjectにしてコールバックハンドラに返す。といった事が効いていると思います。Q4M可愛いよQ4M。

Web周りに関しては、普通にHTTP::EngineとMouseだけでやってます。FrameworkなんかこのレベルだといらなくてHTTP::Engineだけで事足りますわね。
あ、index.htmlだけHTTP::Engine::Middleware::Staticで出してますよ。

ということで、どうぞご利用下さい。

Posted by Yappo at 13:41 | Comments (1) | TrackBack

2009年04月13日

Q4MをMacPortsのMySQL環境に入れる方法

macportsでmysql入れると /opt/local/lib/mysql5/mysql とかいう独創的な所にライブラリが入るので、そのまんまのQ4Mのconfigureじゃ./configureすら上手く動かないし、ググっても良くわからないのでてっとり早くconfigure.inを書き換えたよ。

パッチはhttp://gist.github.com/94339から
実行令とかは下記の通り。

 $ patch < ../for-macports.patch
 $ autoconf
 # include ディレクトリを追加するのが必要
 $ CPPFLAGS=-I/opt/local/include ./configure --with-mysql=/opt/local/var/macports/sources/rsync.macports.org/release/ports/databases/mysql5-devel/work/mysql-5.1.33 --with-mysql_config=/opt/local/bin/mysql_config5

という感じで--with-mysql_configオプションを追加してmysql_configにライブラリパスとかの解決を行わせています。

あとはsudo port install boostとかするの忘れなければはまらない予定。

installおわったら

 $ mysql5 -u root < support-files/install.sql
して、気が向けば perl ./run_tests.pl してチェックすれば無事install完了です。

添削ありましたら、ご指摘くだしあ。

どうでも良いけどQueue::Q4Mのテストデータベースのデフォルトは q4m_test じゃなくて test_q4m が良い。なぜならば mysqld の初期設定で test_% ってのはテスト用として権限設定されてるから。
僕はtest_q4m作って

 $ Q4M_DSN=test_q4m make test 
しました。

Posted by Yappo at 19:22 | Comments (0) | TrackBack

2009年04月02日

Safari3のメモリ管理が何か変?

今のところSafari3限定 (確認したのはバージョン 3.2.1 (5525.27.1))なのだが、IMGタグを追加したりremoveしまくってたりすると、どんどん使用メモリが増えてくる現象を発見した。
Safari4のβ版やらFirefoxではそういった事にならないのは確認したが、単純なDOM操作なのにもりもりメモリを使って行く。
ウインドウを閉じてもメモリは解放されずに、解放しなかったメモリは内部的に再利用してるっぽい。
で、閉じる前に確保してたメモリ領域を使い切ったっぽいポイントでまたメモリをもりもり食べ出す。
まるでメモリプールみたいな感じなんだがウインドウを閉じるまで再利用されてない感じなんだ。

ちなみにSRC属性を指定しないとメモリがもりもり増えなかったりする。

以下のHTMLをローカルに保存して、保存した所と同じディレクトリにdummy.pngという適当な画像を置いてからブラウザで開いて下さい。
メモリが増える様子はアクティビティモニタ等で見るとわかり易いでしょう。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
    <title>memory leak test</title>

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta http-equiv="content-script-type" content="text/javascript">

    <script>
        var count = 0;
        var is_run = true;

        var $ = function(id){
            return document.getElementById(id);
        };

        var reload = function(){
            var container = $("container");
            while (container.childNodes.length > 0) {
                container.removeChild(container.childNodes[0]);
            }
            add();
        };

        function add(){
            $("count").innerHTML = count++;
            var i;
            for (i = 0; i < 100 ; i++) {
                var img = document.createElement('img');
                img.src = "dummy.png";
                $("container").appendChild(img);
            }
            if (is_run) setTimeout(reload, 100);
        }

        window.onload = function(){
            $("reload").addEventListener("click", reload, false);
            $("stop").addEventListener("click", function(){
                is_run = false;
            }, false);
            add();
        };
    </script>
</head><body>
    <div id="stop">stop</div>
    <div id="reload">reload</div>
    <div id="count">0</div>
    <div id="container"></div>
</body></html>
きっとamachangなら理由わかってそうだなー。という気はしてる。

おまけ

leaksコマンドと言う便利コマンドがあるので、実行したりウインドウ閉じたり開いたりした時の結果もはっときます。
なんか色々leakしてるけど、今回と関係あるかどうかはわからない。

実行当初
$ leaks  7011
Process 7011: 199039 nodes malloced for 19823 KB
Process 7011: 0 leaks for 0 total leaked bytes.
どんどんメモり増える
$ leaks  7011
Process 7011: 305529 nodes malloced for 30869 KB
Process 7011: 0 leaks for 0 total leaked bytes.
凄い増えた
$ leaks  7011
Process 7011: 1067031 nodes malloced for 107063 KB
Process 7011: 0 leaks for 0 total leaked bytes.
アクティビティモニタのRSIZEももりもり増える
ウインドウ閉じる
$ leaks  7011
Process 7011: 205175 nodes malloced for 20180 KB
Process 7011: 1 leak for 16 total leaked bytes.
Leak: 0x1ca2dbc0  size=16	instance of 'TSMInputSource', type CFType, implemented in HIToolbox	
	0xa05bcee0 0x15015080 0x00000004 0x00000000 	..[..P..........
mallocedのサイズが減ってるけどRSIZは変わらず。そして1個リーク。
ウインドウ開いた
$ leaks  7011
Process 7011: 205273 nodes malloced for 20262 KB
Process 7011: 4 leaks for 64 total leaked bytes.
Leak: 0x16c0d300  size=16	instance of 'TSMInputSource', type CFType, implemented in HIToolbox	
	0xa05bcee0 0x02015080 0x00000004 0x00000000 	..[..P..........
Leak: 0x1ca2dbc0  size=16	instance of 'TSMInputSource', type CFType, implemented in HIToolbox	
	0xa05bcee0 0x15015080 0x00000004 0x00000000 	..[..P..........
Leak: 0x1ca376a0  size=16	instance of 'TSMInputSource', type CFType, implemented in HIToolbox	
	0xa05bcee0 0x01015080 0x00000004 0x00000000 	..[..P..........
Leak: 0x1cae0120  size=16	instance of 'TSMInputSource', type CFType, implemented in HIToolbox	
	0xa05bcee0 0x03015080 0x00000004 0x00000000 	..[..P..........
RSIZEかわらず。3個リーク増えた。
再度実行
$ leaks  7011
Process 7011: 269750 nodes malloced for 26522 KB
Process 7011: 4 leaks for 64 total leaked bytes.
Leak: 0x16c0d300  size=16	instance of 'TSMInputSource', type CFType, implemented in HIToolbox	
	0xa05bcee0 0x02015080 0x00000004 0x00000000 	..[..P..........
Leak: 0x1ca2dbc0  size=16	instance of 'TSMInputSource', type CFType, implemented in HIToolbox	
	0xa05bcee0 0x15015080 0x00000004 0x00000000 	..[..P..........
Leak: 0x1ca376a0  size=16	instance of 'TSMInputSource', type CFType, implemented in HIToolbox	
	0xa05bcee0 0x01015080 0x00000004 0x00000000 	..[..P..........
Leak: 0x1cae0120  size=16	instance of 'TSMInputSource', type CFType, implemented in HIToolbox	
	0xa05bcee0 0x03015080 0x00000004 0x00000000 	..[..P..........
またまた増えた
$ leaks  7011
Process 7011: 1354957 nodes malloced for 131749 KB
Process 7011: 4 leaks for 64 total leaked bytes.
Leak: 0x16c0d300  size=16	instance of 'TSMInputSource', type CFType, implemented in HIToolbox	
	0xa05bcee0 0x02015080 0x00000004 0x00000000 	..[..P..........
Leak: 0x1ca2dbc0  size=16	instance of 'TSMInputSource', type CFType, implemented in HIToolbox	
	0xa05bcee0 0x15015080 0x00000004 0x00000000 	..[..P..........
Leak: 0x1ca376a0  size=16	instance of 'TSMInputSource', type CFType, implemented in HIToolbox	
	0xa05bcee0 0x01015080 0x00000004 0x00000000 	..[..P..........
Leak: 0x1cae0120  size=16	instance of 'TSMInputSource', type CFType, implemented in HIToolbox	
	0xa05bcee0 0x03015080 0x00000004 0x00000000 	..[..P..........
もっかいウインドウ閉じた
$ leaks  7011
Process 7011: 209735 nodes malloced for 20861 KB
Process 7011: 5 leaks for 80 total leaked bytes.
Leak: 0x16c0d300  size=16	instance of 'TSMInputSource', type CFType, implemented in HIToolbox	
	0xa05bcee0 0x02015080 0x00000004 0x00000000 	..[..P..........
Leak: 0x1ca2dbc0  size=16	instance of 'TSMInputSource', type CFType, implemented in HIToolbox	
	0xa05bcee0 0x15015080 0x00000004 0x00000000 	..[..P..........
Leak: 0x1ca376a0  size=16	instance of 'TSMInputSource', type CFType, implemented in HIToolbox	
	0xa05bcee0 0x01015080 0x00000004 0x00000000 	..[..P..........
Leak: 0x1cadd650  size=16	instance of 'TSMInputSource', type CFType, implemented in HIToolbox	
	0xa05bcee0 0x0b015080 0x00000004 0x00000000 	..[..P..........
Leak: 0x1cae0120  size=16	instance of 'TSMInputSource', type CFType, implemented in HIToolbox	
	0xa05bcee0 0x03015080 0x00000004 0x00000000 	..[..P..........
リーク増えた

Posted by Yappo at 21:04 | Comments (3) | TrackBack

2009年03月31日

クロスブラウザ対応やってみて思った事

HTMLやらCSSやらJavaScriptやら色々弄った感想

- Firefox, Safari, Google Chrome なんかは割と手がかからない
- Opera も上の3つ抑えてればだいたいok
- なんかSafari4のJavaScriptの挙動が3と微妙にちがう
- IEは死ね、IE7からだいぶ互換性的な物がよくなってるけどIEは死ね。
-- IE6のサポートを切り捨てる時代はまだか?
- IE8は確かにJavaScriptが速くなってるがGoogle Chromeは劣るしSafariとか本当速い、Firefox3.0は結構遅い
- z-indexの事を考えてないで作ってると、いざとなったら本当にびっくりする
- pngの透過画像をあわせるのは案外しんどい
-- DXImageTransform.Microsoft.AlphaImageLoader使うんだけど、background-imageが入ってると混ざる、そしてDXImageTransform.Microsoft.AlphaImageLoaderで出すと画像が背景画像じゃなくなる
-- classにpngimgみたいなのが入ってるときはbackgroundをnoneにするのやってみたけど、#idname:hover {} みたいに hover されたときだけpng画像を変えたりとかenable/disableクラス与え状態によってpng画像のurlを変えたりすると上手くDXImageTransform.Microsoft.AlphaImageLoaderが当たんなくなる
- 元から配布されてるjqueryライブラリを俺俺改造されてると他の人が困るので、元のは弄らずに外部からわかり易くmethod差し替えたりするとよい。
- アンダースコアハックとかCSSの人がハックハック言ってる物はPHPのクラス名の区切りにバックスラッシュ使うようなもんだと思ってるから使いたく無い
-- ブラウザ毎のCSSを吐き出すジェネレータ書いてHTMLから読む時にブラウザによって変えるのが正解なんだろなー

- float: leftしまくった要素を持つ親要素の縦横も、IEだけは float: left してる要素分だけ加算されるので、上のブラウザと全然違う事になったからjavascriptで縦横辻褄合わせた。
-- たいていの非互換製はJavaScript使う力技でなんとかなったり
- IE6なんかはpadding-leftの値を1px変えるだけですっきりしたり

まとめ


たんぽぽを乗せるだけの簡単な仕事じゃないんだけど、殆どの苦労は機械的に解消出来そうな感触を得た春であった

IEを使わないでJavaScriptを書く時に陥る一番の罠としてはハッシュの最後の要素に,を付けてしまうという事(Perlでは皆よくやってる)だが

var hash = {
key: name,
last: value, // ここの ,
};

これはIEでは動かないのだが、コードが多くなると探すのがとても大変である。
が、そんな時はJavaScript Lintを使えば良い。
アプリケーションのユニットテストの中に、これを使ってlintかけるテストなんか入ってると興奮が止まらないだろう。
たとえば
#!/usr/bin/perl
use strict;
use warnings;
use Test::More;
use Text::SimpleTable;
plan skip_all => 'this test requires "jsl" command' unless `jsl` =~ /JavaScript Lint/;

my @files = <htdocs/js/*.js>;
plan tests => 1*@files;

my $table = Text::SimpleTable->new(25, 5, 5);

for my $file (@files) {
# 0 error(s), 6 warning(s)
my $out = `jsl -stdin < $file`;
if ($out =~ /((\d+) error\(s\), (\d+) warning\(s\))/) {
my ($msg, $err, $warn) = ($1, $2, $3);
$file =~ s!htdocs/js/!!;
$table->row($file, $err, $warn);
is $err, 0, $file;
} else {
ok 0;
}
}
diag $table->draw;

こんなのを書いてもらって使ってる。

これ使ってると、「ああ、JavaScriptのスコープってfunction毎なんだな」ってのが良く思い出せて良いです。

(はてなに書こうとしてたフォーマットをそのままコピペしたのでみにくいかなっと)

Posted by Yappo at 13:44 | Comments (2) | TrackBack

2009年01月16日

コードホスティングサイトの比較表を作っています

最近「GitHubみんな使っててCodeReposやばいねー」とか聞かれる時があって、適当に返事するのもアレなんで、客観的に返答出来るように比較してみようかなーと思い、それぞれのサービスの比較表を作ってみる事にしました。

現在http://soozy.org/index.cgi?CodeHostingComparisonにて表を作っています。
現在は、SourceForge, Google Code, CodeRepos, GitHubの4サイトから比較しています。
はてなアカウントがあれば自由に編集出来ますので(まずは左上のloginをクリック)、足りない所があれば、他のサイト追加、比較項目追加、内容修正など行って頂ければ嬉しいです。

比較項目を考えるのがとても大変なので、是非皆様のお知恵を拝借したく思いますです。

Posted by Yappo at 13:39 | Comments (1) | TrackBack

コードホスティングサイトの比較表を作っています

最近「GitHubみんな使っててCodeReposやばいねー」とか聞かれる時があって、適当に返事するのもアレなんで、客観的に返答出来るように比較してみようかなーと思い、それぞれのサービスの比較表を作ってみる事にしました。

現在http://soozy.org/index.cgi?CodeHostingComparisonにて表を作っています。
現在は、SourceForge, Google Code, CodeRepos, GitHubの4サイトから比較しています。
はてなアカウントがあれば自由に編集出来ますので(まずは左上のloginをクリック)、足りない所があれば、他のサイト追加、比較項目追加、内容修正など行って頂ければ嬉しいです。

比較項目を考えるのがとても大変なので、是非皆様のお知恵を拝借したく思いますです。

Posted by Yappo at 13:39 | Comments (1) | TrackBack

2008年12月20日

WEB+DB PRESS Vol.48に寄稿しました

今度発売されるWEB+DB PRESS Vol.48の第一特集にて「[言語別]モダンプログラミング入門」 という記事を書かせて頂きました。

おこがましいようですが僕は特集の総括的な部分とPerlに関して担当させて頂きました。
KENTは悪じゃない!から始まってperldoc, cpan, pauseアカウントの取得, test, shipit そして JPA まで幅広く今のPerlについて書きました。
もちろん濃くて広い事を書くにはページ数の限界もあって「薄く広く足がかりを作る」に専念したため、Shibuya.PMで発表してるような魑魅魍魎が満足するような内容にはなっていませんが、昨今のPerlを見つめ直す流れに乗っ取り、他言語な方や初心者の方でも今のPerlの流れに乗れるような内容になる事を意識しました。

もちろん他の言語(Ruby,Java,PHP,Javascript)でも、似たような構成と主旨で書かれています。
それぞれの章を担当して下さった皆様にも感謝です。

今回はとても幸運な事に、ただ単に特集の一つを担当したわけではなく、コンセプト的な企画を作る所から関わらせていただけました。
というもののきっかけとしてはITmediaで取材して頂いた時の一言

—— 開発系の雑誌で購読してるものはありますか? 雑誌にはどんなコンテンツを期待したいですか?

SoftwareDesignとWeb+DB PRESS。東京IT新聞も速報度の面でがんばっているなと思います。ぶっちゃけ雑誌媒体というのはWebの情報に比べると鮮度が悪いわけですが、紙には紙の良さがあってじっくりと読むのには向いていますよね。言語は問わず(商業的な取捨選択はあるけど)今風のモダンでcoolなコードの書き方などをメインにした「プログラム専門誌」が欲しいですね。月刊で。
がきっかけでした。
流石に月刊はアレですが、夢が叶ったという事でとても嬉しいです。

このへんのやってみて思った事はtakesakoさんすげーって事。

ってことで1家に一冊、1部署に一冊是非どうぞ。

WEB+DB PRESS Vol.48
WEB+DB PRESS Vol.48
posted with amazlet at 08.12.20
WEB+DB PRESS編集部 編
技術評論社
売り上げランキング: 585

そしてやっっぱり相変わらず思う事は、プロの編集者さんはすごいということと、また機会があれば何か書きたいなということでした。

あ、執筆中はwassrでhyoshiokaさんからの貴重なアドバイスも頂きました事を追記しておきます。

otsuneさんに前回の紹介で「もう出てると思って買ったら1号前だった」とクレームが来たので書店に並びそうになるまで待ちました。

Posted by Yappo at 19:08 | Comments (0) | TrackBack

2008年12月12日

このblogとperl-users.jpは移転完了

blog.yappo.jp と perl-users.jp だけは、新環境に移行したのでサーバの物理移動中も止まらないす。

しかしふっるいmtなので関連ディレクトリをrsyncするだけで動くなんてすばらしいなー

Posted by Yappo at 19:32 | Comments (0) | TrackBack

2008年12月10日

サーバ引っ越し計画

すっかり準備するのがギリギリになってヤバイ。
金曜の夜に今置いてる所から物理的にサーバを移動します。
なのでもう今週中はテンパってます。

という事で簡単な計画表

やること

  • DNSのプライマリサーバ移転 (hidekさんの会社のやつ契約ずみ) (jprs/tonic/value domain)
  • mail/irc/plagger環境作る (リアルサーバでOSとかは既に入って稼働してるの使い回し)
  • edge serverでメールを受けてバックエンドに再配送させる仕組みつくる
  • edge serverにマトモなdsn cacheを入れる
  • このblogや軽いwebサービスようのDomU作る
  • perl-users.jp / soozy.org / shibuya.pl / perldoc.jp / yapc.asia などようのDomUつくる
  • 新しい環境の中に25番ポートで繋がるようにする
  • ラックの掃除
  • 新環境を用意するものは、新環境にさっさと移動、用意しないのは金曜の夜に物理マシンの移動
  • 移動中のお知らせメンテナンスページ用意
  • /etc/hosts とか hostname まわり。

異動前の構成とサービス内容

PE750

  • mail - sendmail (virtusertable) - mew - spamd (procmail(hiyoko@twitter, kacotie@twitter))
  • irc - irssi - oppaisan - mobirc
  • plagger
  • private subversion repos
  • dns
  • 以下はweb
  • yappo.jp/yappo.ne.jp (i, 503, moogle, talk, trac, svn, w, dir, search, *.labs, blog, tec)
  • blogdb.jp (bulkya, mfpm, shibuya.burogukyoukai)
  • menulist.jp
  • soozy.org
  • bloxab.org
  • cybozu.co.uk
  • perl-users.jp
  • seiitaishougun.com
  • shibuya.pl
  • yapc.asia

ISP1100

ハードウェアクロックがなんだか年単位でずれてる。といかどっかのDomUに突っ込んで退役希望

  • web crawler
  • hiyoko
  • sendmail virtusertable
  • mobile sns用のメール受信処理
  • moblog & photo storage用のメール受信処理
  • mail配送エンジン(たしかもう使ってない)
  • 以下はweb
  • bp.to
  • m.blogdb
  • 2ch proxy

PE1850

  • mysql
  • mysql with senna

edge server

codereposとacotieへのreverse proxyやらなんやら

SC440 - 1

  • coderepos
  • acotie

SC440 - 2

今なにもない。あ、1000スピーカカンファレンスで使った。

tsukumo

dns セカンダリとblogdb.jp跡地

異動後の構成とサービス内容

PE750

京都行ってる時にとまりやがったのでこわい。

  • private subversion repos
  • 以下はweb
  • yappo.jp/yappo.ne.jp (i, 503, moogle, talk, w, dir, search, *.labs)
  • blogdb.jp (bulkya, mfpm, shibuya.burogukyoukai)
  • menulist.jp

ISP1100

ハードウェアクロックがなんだか年単位でずれてる。といかどっかのDomUに突っ込んで退役希望、というか移動した後bootするか不明。

  • web crawler
  • hiyoko
  • sendmail virtusertable
  • mobile sns用のメール受信処理
  • moblog & photo storage用のメール受信処理
  • mail配送エンジン(たしかもう使ってない)
  • 以下はweb
  • bp.to
  • m.blogdb
  • 2ch proxy

PE1850

平穏無事に動いてるのでこわい

  • mysql
  • mysql with senna

edge server

codereposとacotieへのreverse proxy server 並びに mail forwarder

SC440 - 1

  • coderepos
  • acotie

上のDomUに加えて下のDomU追加

public

  • perl-users.jp
  • shibuya.pl
  • soozy.org
  • yapc.asia (もしくは edge server のみで処理)

private

  • private subversion repos for svn.yappo.jp
  • yappo.jp/yappo.ne.jp (trac, svn, blog, tech)
  • bloxab.org
  • cybozu.co.uk
  • seiitaishougun.com

SC440 - 2

  • mail - sendmail (virtusertable) - mew - spamd (procmail(hiyoko@twitter, kacotie@twitter))
  • irc - irssi - oppaisan - mobirc
  • tig/wig
  • plagger

tsukumo

dns セカンダリとblogdb.jp跡地

hidekさんの会社のVPS

dns プライマリとバックアップ

PE860

状況をみてPE750とISP1100のサービスをこれのDomU複数作って集約。集約したらPE750/ISP1100を退役。余裕があればPE1650も入れたいけど80万くらいしたからどうしようか。

作業する順番

  • VPSにname serverの環境作ってprimary として動かし始める
  • yappo.ne.jpのnsレコード変更。変更出来次第他のドメイン全部のnsレコード変更
  • DomU2個作る(1個作ってイメージコピー)
  • VPSにバックアップしまくる
  • mail/irc/plagger環境作る
  • edge server から SC440-2 にメール流す
  • public servicesの引っ越し (済: perl-users.jp)
  • private servicesの引っ越し (済: blog.yappo.jp)
  • VPSにバックアップ(差分とか)
  • イーサケーブル作ってラックの掃除
  • PE750/PE1650/ISP1100物理移動
  • ラッキング
  • サーバ起動
  • hostname/ip address/ip tables/network環境の書き直し
  • DBの認証設定全部変える
  • アプリケーションのDB設定全部変更
  • アプリケーション稼働確認と広告周りを実機でチェック
  • ISP1100のメール環境整備
  • クロウラー走らせる
時間足りなくてきついわー

来年

codereposとか入ってるマシンに500GのHDDが刺さってるだけなので vgextend VolGroup00 /dev/sdb してパーティションサイズをいつでも増やせるようにしておく。

Posted by Yappo at 18:36 | Comments (0) | TrackBack

2008年09月01日

CodeReposが1年たってGitリポジトリ追加の巻

昨晩は夜9時から誕生日ケーキを探してたけどケーキ屋さん店じまいしてるのばっかで誕生日中にエントリかけなくなった><

YappoLogs: CodeRepos - 個人レポジトリを共有しよう!計画という記事と共にCodeReposが生まれて一年経ちました。
僕は主に460名分のhtpasswdをひたすら登録をするだけのお仕事をしていたわけですが正直ここまで続くとは思っていませんでした。
これも何もひとえにがんがんコミットしてくれる皆様のお陰だと思っています。有り難うございました。
やっぱり折角人様のコードを弄くりまくれる環境があるのだから、皆ももっとコミットしまくれば良いよ。

あと折角一年経ったという事でリリースし忘れてたGitリポジトリを公開しておきます。
http://git.coderepos.org/です。
GitはSubversionとは違って全部を一つのリポジトリに突っ込むととてもとても不愉快な事になるので、プロジェクト毎にリポジトリ作れるようにしました。
create repository のとこに作成したいリポジトリのパスを入れてsubmitすればおkです。
Subversionのリポジトリと同じルールの階層でしか作れないようになってます。
あとは作ったリポジトリに対してgit pushやらすればおkです。
リポジトリ作った時やgit pushした時にFeedを吐くようにしてあり、そのFeedをcodereposbotがircに流してくれるという事もやってます。
もうすこし詳細を見るにはわっふるわっふるしてください。

何はともあれ2年目のCodeReposをよろしくお願いします。

Posted by Yappo at 11:47 | Comments (1) | TrackBack

2008年08月09日

MixiEchoPodというMacからmixiのエコーを快適に使うツールを作ったよ

空前のwassrブームの中皆様いかがおすごしでしょうか。
ついにあのTwitがとくにエコー対応していなくて面白い感じですが、Mac用のいいツールが無さげです。というかAPI解放してないけどEchoPodとかあります。
先週末の、Wassr大会議#2の集いにtokuhiromさんもいらしてたのでエコーに乗り換えてもいいか聞いてみたのですが、「Wassrを末永くお願いします」と言われたので、僕が勝手にTwitterPodをエコー対応しちゃいました。
かいつまむと「mixiエコーをtwitter APIを使うクライアントからアクセスできるコンバータ付きproxy」です。

Macのターミナルとperlが使える環境の人前程ですが、物凄く簡単にエコー対応が出来ます。
TwitterPodをアプリケーションディレクトリに入れておいて下さい。
そして、ここからターミナル操作です。

まずは

svn co http://svn.coderepos.org/share/lang/perl/misc/MixiEchoPod ~/MixiEchoPod
とかで、仕組み一式をチェックアウトして
 $ cd /Applications
 $ ~/MixiEchoPod/install.pl
とするだけでMixiEchoPodがアプリケーションディレクトリに出来上がります。
これでMixiEchoPodのインストールは完成です。
何やってるかはinstall.plでも見て下さい。

次に肝心のproxyですが、~/MixiEchoPod/mixiechopod.plがそうです。
これを使うには各種CPANモジュールが必要なので

 $ sudo cpan
> install MooseX::Getopt
> install HTTP::Server::Simple
> install HTTP::Engine
> install JSON
> install DateTime
> install XML::Simple
> install MooseX::Types
とかして必要なモジュールを全部入れておきます。
あとはsvn headのWWW::Mixi::Scraperも必要なのでsvn.coderepos.org/share/lang/perl/WWW-Mixi-Scraper/trunkからチェックアウトしてインストールです。
ここまでして入れたら
 $ ~/MixiEchoPod/mixiechopod.pl --port 3941
で起動します。3941はproxyのサーバポートです。
起動したらemailとpasswordを聞かれるのでmixiのアカウントに使ってる物を入れて下さい。

ここまできたらあとはアプリケーションディレクトリのMixiEchoPodを起動して、設定画面のアカウントは適当なのを入れて、最後が肝心だけど「Enable Proxy」にチェックをいれて「Server」に「127.0.0.1」を入れ「Port」に「3941」を入れればokです。
結構無理栗なhackなのでMixiEchoPodのアプリケーションが落ちちゃったりする可能性もありますが僕は結構快適に使えてます。

今後の予定はmixiならではの機能をMixiEchoPodから使えるようにmixiechopod.plを拡張してくネタをmixiが実装してくれたらいいですね。
なんでも一から作るのは大変ですが、この程度なら大変じゃなくて良い感じですね。

どうぞご利用下さい。

Posted by Yappo at 18:46 | Comments (1) | TrackBack

2008年07月18日

CodeRepos の引っ越し作業が一通りおわりました

一応、無事に一通りの引っ越し作業がおわりました。
細かい所は週末のうちに全部終わらせる。
実際どういう環境になったのかはあとで書く。

Posted by Yappo at 11:41 | Comments (1) | TrackBack

2008年07月09日

CodeReposのサーバお引っ越し計画

以前予告した通り、CodeReposサーバのお引っ越しを今週中に行います。
とりあえず場所は家に置いて、さっき電力会社に電源工事発注した。
リバースproxyの部分にCentOSの新しいのをいれて、coderepos自体はバックエンドにいるXenのインスタンスで動かそうと思ってます。
QX6600 8G メモリの環境なのでcoderepos以外のインスタンスとかも十分に対応できそう。

既にiscsiの環境もあってライブマイグレーションとか出来るようにはなってるんだけど、それやると別途ファイルサーバ持たなきゃ行けないとかQX6600なCPUのマシンが一台しかないから、別のホストマシンにインスタンス移したらカーネルがクラッシュするとかで、どうしようか悩んでる。
別にこの規模じゃそういうのいらないかなぁ。

で、それらの環境を今晩から1から作ろうと思ってたら、年始に遊んでた環境がそのまま使えそうな事を発見。
xenのインスタンスを新規に作ってしまえばOS環境の設定は楽に終わりそうな気がしたけど、今流行ってるXenの管理ツールを使いたいなと思っていて誰かにおすすめを聞きたい所。

ちなみに良い案が無ければYappoLogs: Cobbler Koan を CentOS な Xen で動かしたよで作った環境でxenのイメージを作る予定。
イメージファイルをiscsiじゃなくてローカルディスクに置いて、iscsiのマシンに依存しない方向で運用しときたい予定。
仮想ディスクはSparseという実際に使ったぶんしか実際のディスクサイズが食われないというwrite性能の低いフォーマットを使う予定で(参考文献)す。バージョン管理システムだから問題無いよね?

ちなみに移行自体は、新しい環境にtracとかもろもろ入れて、svnはdump/loadしてtracはsqliteのファイルをコピペしてくるだけの簡単なお仕事です。

メンテナンス開始日時の具体的な予定は立てられないので、作業直前に各種ircチャンネルやtwitterで告知を行います。

coderepos専用のインスタンス作るので、codereposのadmin的な意味でサーバのログインアカウントを任意の誰かに渡せると思います。
#coderepos@irc.freenode.netではxenとかに詳しいエンジニアを募集します!報酬はありません!!!

EC2でやれって話?とりあえず金曜までにやんなきゃいけないので勘弁してくだちぃ。

Posted by Yappo at 14:51 | Comments (1) | TrackBack

2008年07月07日

WassrPodというMacからwassrを快適に使うツールを作ったよ

空前のwassrブームの中皆様いかがおすごしでしょうか。
ついにあのTwitがTwit4WSとしてwassr対応して面白い感じですが、Mac用のいいツールが無さげです。
先週末の、はてなハイククライアント制作者の集いにdrkinさんもいらしてたのでwassr対応を聞いてみたのですが、ちょっと面倒くさそうな感じだったので、僕が勝手にTwitterPodをwassr対応しちゃいました。
かいつまむと「wassr APIをtwitter APIを使うクライアントからアクセスできるコンバータ付きproxy」です。

Macのターミナルとperlが使える環境の人前程ですが、物凄く簡単にwassr対応が出来ます。
TwitterPodをアプリケーションディレクトリに入れておいて下さい。
そして、ここからターミナル操作です。

まずは

svn co http://svn.coderepos.org/share/lang/perl/misc/WassrPod ~/WassrPod
とかで、仕組み一式をチェックアウトして
 $ cd /Applications
 $ ~/WassrPod/install.pl
とするだけでWassrPodがアプリケーションディレクトリに出来上がります。
これでWassrPodのインストールは完成です。
何やってるかはinstall.plでも見て下さい。

次に肝心のproxyですが、~/WassrPod/wassrpod.plがそうです。
これを使うには各種CPANモジュールが必要なので

 $ sudo cpan
> install MooseX::Getopt
> install HTTP::Server::Simple
> install HTTP::Engine
> install JSON
> install DateTime
> install XML::Simple
とかして必要なモジュールを全部入れておきます。
ここまでして入れたら
 $ ~/WassrPod/wassrpod.pl --port 9277
で起動します。9277はproxyのサーバポートです。

ここまできたらあとはアプリケーションディレクトリのWassrPodを起動して、設定画面からwassrのアカウントを入れて、最後が肝心だけど「Enable Proxy」にチェックをいれて「Server」に「127.0.0.1」を入れ「Port」に「9277」を入れればokです。
結構無理栗なhackなのでWassrPodのアプリケーションが落ちちゃったりもしますが、結構快適に使えます。

今後の予定はwassrならではの機能をWassrPodから使えるようにwassrpod.plを拡張してく感じです。
なんでも一から作るのは大変ですが、この程度なら大変じゃなくて良い感じですね。

どうぞご利用下さい。

Posted by Yappo at 17:51 | Comments (1) | TrackBack

2008年03月03日

誰でも簡単にOpenID 2.0なOPを作る方法 and CodeReposでOpenID(2.0対応)プロバイダの提供始めましたのお知らせ

先週のbuilder techtalkから俄然としてOpenIDが熱くなって来た今日この頃いかがお過ごしでしょうか。
先日参加して来たOpenID Hackathonの成果として、CodeReposがOpenIDのOpenID 2.0 Providerになりましたことをお知らせします。
CodeReposのアカウントをお持ちの方は、fastladderとかLIMLICとかのOpenIDでサインオンできるサービでOpenID URLをcoderepos.orgとだけ打ち込んでログインしてみて下さい。
2.0に対応していない所だったらhttp://coderepos.org/share/wiki/Committers/usernameとでも入れればいいと思います。
はてなもOpenIDでログイン出来るはずなのにOpenID URL入れる所が無くてドン引きした。
暫定でIdentityをhttp://coderepos.org/share/wiki/Committers/usernameという形にしてありますが、もっと良い案がありましたら教えてくださいまし。

OpenID Hackathonに参加するまでは今イチOpenIDの仕様が判ってなかったですがようやく判って来ました。
なんだかPerlでOpenID 2.0 Serverに対応してるモジュールが無かったっぽいんですが、code.sixapart.comのリポジトリkazeburoさんのパッチをあてたら普通に2.0のOP作れてビックリしました。
このパッチもOpenID Hackathonの成果でしたっけ?

本来ならtracにOpenID OP pluginか何かを入れてやるんでしょうが、今回は勉強しながら作ったのでいびつな構成かもしれませんし、きっとZIGOROuさんがDISってくれるので、そのDIS記事見ながら改善します。

超簡単なOpenID 2.0対応のOP作り方

仕様を咀嚼してないのですが、CodeReposではこうやったよ!という例をメモります。
CodeReposのOpenID対応に関しての必要なコードやらテンプレートもCodeReposにコミットされてるので詳細はそっちで。

自分なりの用語の理解として

  • OP=認証サーバ
  • RP=OPの認証を貰う外部サイト
  • xrds=認証に必要な情報を入れた容器
  • Identity=ユニークなIDになれるURL
こんな感じ

server xrdsをRPに見つけてもらう。

RPのOpenID URLにcoderepos.orgとかを入れた時にRPはどうやって認証URLを見つけるかというと、その入力されたドメインのHTTP HEADにあるX-XRDS-Locationというヘッダに入っているURLに書いてあるファイルを見てend pointを探します。
(余談だけどHackathonでDavidに、それDNSのTXTレコードとか使えば良いんじゃないか?と聞いてみたら「更新に時間がかかるでしょ」と。納得。)

Apacheの設定だと

Header add X-XRDS-Location http://openid.coderepos.org/server.xrds
を入れるだけ。
mime typeも合わせとかなきゃいけないので
AddType application/xrds+xml .xrds
も必須。
中身は
<?xml version="1.0" encoding="UTF-8"?>
<xrds:XRDS
    xmlns:xrds="xri://$xrds"
    xmlns:openid="http://openid.net/xmlns/1.0"
    xmlns="xri://$xrd*($v*2.0)">
  <XRD>
    <Service priority="0">
      <Type>http://specs.openid.net/auth/2.0/server</Type>
      <URI>http://openid.coderepos.org/auth</URI>
    </Service>
  </XRD>
</xrds:XRDS>
こんな感じす。

認証する仕組みを作る

さっきのNet::OpenID::Serverにkazeburo patchを当ててhttp://svn.coderepos.org/share/websites/coderepos.org/openid/ここにあるようなコードを書いた。

IdentityのHTML中にメタ情報を入れる

RPはOPから渡されたIdentity URLに実際アクセスをして必要な認証情報の妥当性を見つけようとしてるらしいので、tracのテンプレートに

<?cs if:title ?><?cs if:string.find(title, 'Committers/') == 0 ?>
<link rel="openid2.provider" href="http://openid.coderepos.org/auth" />
<link rel="openid.server" href="http://openid.coderepos.org/auth" />
<?cs /if ?><?cs /if ?>
を追加してCommittersページの時だけlinkタグを出すようにした。
これ書くことでOpenID 1.1のOPにもなれてるんだと思う。
そして、大事な物としてIdentity URLのRespons HEADで吐くX-XRDS-Locationの中身をさっきのとは違うのにしとかなきゃいけなくて
<Location /share/wiki/Committers>
    Header unset X-XRDS-Location
    Header add X-XRDS-Location http://openid.coderepos.org/signon.xrds
</Location>
と書いて対応。
中身は
<?xml version="1.0" encoding="UTF-8"?>
<xrds:XRDS
    xmlns:xrds="xri://$xrds"
    xmlns:openid="http://openid.net/xmlns/1.0"
    xmlns="xri://$xrd*($v*2.0)">
  <XRD>
    <Service priority="0">
      <Type>http://specs.openid.net/auth/2.0/signon</Type>
      <URI>http://openid.coderepos.org/auth</URI>
    </Service>
  </XRD>
</xrds:XRDS>
こんなのになる。
これが良くわかってなくて一番はまった。

認証を実装

さっきPerlで書いたっていった認証 CGIの部分は実際は認証処理をしてません。
というかBasic認証でやっちゃいますので。その認証URLを見るにはBasic認証が必要なように設定します。
svnもtracもBasic認証使ってるからこそできる手抜きですね!
ただ一点気をつけないといけないのはPOSTの時は認証しないようにしとくこと。
何でかって言うとRPが認証URLにPOSTで何かしにくるから!何してるか良くわかんないけど何かPOSTしてる!

おわりに

以上の手順でOpenID 2.0対応のOPを簡単に作ることができました。
CodeReposのアカウントを持っている人は全員プログラムのコードを書けることが保証されていて(ISPのSLA的な意味で)、アカウント持ってる人数も250人を越えているので、CodeReposがOpenIDプロバイダになることは結構面白い試みなんじゃないかと思います。(OpenID Hackathonに参加する口実で作り始めただけだけど)

どう書く?.orgとかCodeGolfとかがOpenIDのRPになって連携出来るようになると面白そうですね。
OAuthとかにも対応するともっと夢が膨らむでしょうか?

海外向けに英語の記事でも書いて自作自演digしたい所だけど、英語で長文書くのがしんどいからAjiajinで英語版の記事を誰かが書いてくれるのを気長に待つ。

という事で、CodeReposのコミッターの方々はどうぞご利用ください。

追記

kazeburo patchは# 2008年03月03日 miyagawa miyagawa openid will commit on Monday. Thanks!!CommentsAdd Starらしいのでpatchもうちょっとしたらコミットされるね。

Posted by Yappo at 16:06 | Comments (1) | TrackBack

2008年01月22日

1000speakersでXenとか話して来ました

先週土曜日に開催された「1000人のダム好きを集めるプロジェクト」にてXenやらCobblerとかの話をして来ました。
発表の様子は↓のニコニコ動画で。というかうまく再生出来ない人が多いからhttp://www.nicovideo.jp/watch/sm2078669からどうぞ。

弾幕とか貼るならこっちから
yappoタグも増えて来たな。

動画環境はcojiさんが私財をなげだして素晴らしい機材を買ってくれたのでとてもかっこ良いustreamが出来ていました。
そして即座にニコニコへuploadするという神業に直立不動が止まりませんでした。

技術系カンファレンスのプレゼン動画がニコニコに溜まって来てるので、そろそろエンジニアMADってジャンルな動画が出て来て欲しいすね。
たとえば今回の発表は全部CCライセンスなのでhttp://www.nicovideo.jp/mylist/4573744ここのエンジニア素材が使い放題!
amachangは大変な強制終了をしていきました的な動画が見たいので誰か作って!

発表時間の30分前まで延々とプレゼンツールの実装をしていて、ネタを確定したのが本番30分前でした。
最初は言語的な話を考えていたのですが、レジュメみたら言語的な発表の比重が多かったので趣向を変えてみました。
デモンストレーションも特に用意していた訳でなく、個人で所有しているXenとかの実験環境にログインしといてそのまま操作しただけでした。

こんなに直前まで話す事を考えていなくても何とかなるとは思っていなかったんですが、結局は自分が面白いと思った事だったら台本が無くても説明出来ちゃう訳なんで、1000speakers dam project でもプレゼン経験無い人がどんどん出て来て成功出来ると思った。
エンジニアとかそういう人種だったら、人に伝えられる引き出しが10個以上常にストックされてて、即座にデモする環境とかを持っているので、トーク経験無い人でも緊張しても良いから出るといいよ。

さて本題ですが、今度の日曜日に鎌倉でSoozy Conference #4が開催されるのですが、懇談会会場予定のお店が最低30名から貸し切りに出来るとの事で、少なくともあと6名くらいの追加参加者を募集しています。
wikiにも書かれていないスペシャルゲストも参加するので、参加制限を緩くしたこの機会に是非ご参加を

関係無いけど

13:14 < t*kuhir*m> ドアドアってなに?
どんびきした

Posted by Yappo at 13:29 | Comments (0) | TrackBack

2008年01月04日

Cobbler Koan を CentOS な Xen で動かしたよ

Xenが熱かった今年ですが皆様いかがおすごしでしょうか。
Koan - mizzy.org - Trac

これで Xen ゲスト OS のインストールがはじまる、はずなんだけど、うちの環境では Segmentation Fault になってしまった。VMWare 上で Xen を動かすというのは無理があるのかもしれない。 実機で試したいところだけど、試せるサーバがないので保留。Yappo さんあたりが試してレポートしてくれるに違いない、きっと。
という牙指令を頂いたので試してみましたよ!

今回の環境をざっと説明すると、Cobblerを入れるマシンはCentOS5.1(i386)な環境で(master server)、cobbler importするディストリビューションはCentOS5.1(x86_64)、koanでネットワークする環境はCentOS5.1(x86_64 xen)な環境(client)です。
Cobblerを入れるマシンでは、元々ネットワークインストールする為のdhcpd,tftpd,httpdなど諸々の環境が入っていたので、とてもとても楽でした。

まず問題なのがmizzyさんはFedora 7っぽいので自分のCentOS 5.1な環境だとmizzyさんの例どおりにはできない!
といってもmizzyさんが参考にした元記事はCentOSでやってるので、そっちを参考にした。
サーバの構築を簡単にするためのステップ (その5:Cobber編 Part1 )
予め/var/lib/cobbler/settiongsで使ってるportを空けておきましょう。

Cobblerが入ったので早速import

master # cobbler import --mirror=/centos/5.1 --name=CentOS5.1
時間はかかるけどimportは簡単に終わりました。
cobblerdとかstartしたりcobbler reportでの確認や、細かい設定はmizzyさんの所を見ながらやって下さい。
Cobbler - mizzy.org - Trac

次はXenゲストOSのインストールです。簡単です。

client # koan --server=192.168.10.1 --profile=CentOS5.1-xen-x86_64 --virt --virtname=koan1
- downloading initrd initrd.img to /var/lib/xen/initrd.img
- url=http://192.168.10.1/cobbler/images/CentOS5.1-xen-x86_64/initrd.img
- downloading kernel vmlinuz to /var/lib/xen/vmlinuz
- url=http://192.168.10.1/cobbler/images/CentOS5.1-xen-x86_64/vmlinuz
- kernel saved = /var/lib/xen/vmlinuz
- initrd saved = /var/lib/xen/initrd.img
reconnect with xm console koan1
installが始まりました。
--virtnameオプションでバーチャルマシン名を指定しておいた方が良いです。
xm console koan1すれば、インストールプロセスを見る事が出来ます。

一件落着の様ですが、xenのimageが/var/lib/xen/images以下に置かれてしまうので、別のディレクトリにxenのイメージファイルを置きたい場合にはストレスが溜まってしまいます。
mizzyさんとこに書いてあるcobbler reportだとvirt-pathみたいな設定があるのですが自分所だと設定出来ません。
どうやらrpmforgeのCobbler/Koanのバージョンが古いせいだったようです。
という事で新しめのバージョンにupdateします。

master # wget ftp://mirror.linux.duke.edu/pub/fedora/linux/extras/6/SRPMS/cobbler-0.6.3-2.fc6.src.rpm
master # rpmbuild --rebuild cobbler-0.6.3-2.fc6.src.rpm
master # rpm -U /usr/src/redhat/RPMS/noarch/cobbler-0.6.3-2.noarch.rpm
client # wget ftp://mirror.linux.duke.edu/pub/fedora/linux/extras/6/SRPMS/koan-0.6.3-3.fc6.src.rpm
client # rpmbuild --rebuild koan-0.6.3-3.fc6.src.rpm
client # rpm -U /usr/src/redhat/RPMS/noarch/koan-0.6.3-3.noarch.rpm
これで新しめになったとおもいます。

準備が出来たはずなので、設定を変更します。

master # cobbler profile edit --name=CentOS5.1-xen-x86_64 --virt-path=/iscsi/xen
master # cobbler sync
master # cobbler profile report
profile         : CentOS5.1-x86_64
distro          : CentOS5.1-x86_64
kickstart       : /etc/cobbler/kickstart_fc6.ks
kernel options  : {}
ks metadata     : {}
virt file size  : 5
virt ram        : 512
virt type       : auto
virt path       :
virt bridge     : xenbr0
virt cpus       : 1
repos           : []
dhcp tag        : default
server          : <<inherit>>

profile         : CentOS5.1-xen-x86_64
distro          : CentOS5.1-xen-x86_64
kickstart       : /etc/cobbler/kickstart_fc6.ks
kernel options  : {}
ks metadata     : {}
virt file size  : 5
virt ram        : 512
virt type       : auto
virt path       : /iscsi/xen
virt bridge     : xenbr0
virt cpus       : 1
repos           : []
dhcp tag        : default
server          : <<inherit>>
無事にXenのイメージファイルのパスが/iscsi/xenに変更されました。

さっそく正しいイメージファイルのパスでinstallできるかやってみます。

client # koan --server=192.168.10.1 --profile=CentOS5.1-xen-x86_64 --virt --virt-name=koan2
- using kickstart from cobbler: http://192.168.10.1/cblr/kickstarts/CentOS5.1-xen-x86_64/ks.cfg
- no virt-type specified, auto-selecting xenpv
libvirt_qemud (pid 2870) を実行中...
downloading initrd initrd.img to /var/lib/xen/initrd.img
url=http://192.168.10.1/cobbler/images/CentOS5.1-xen-x86_64/initrd.img
- using kickstart from cobbler: http://192.168.10.1/cobbler/images/CentOS5.1-xen-x86_64/initrd.img
downloading kernel vmlinuz to /var/lib/xen/vmlinuz
url=http://192.168.10.1/cobbler/images/CentOS5.1-xen-x86_64/vmlinuz
- using kickstart from cobbler: http://192.168.10.1/cobbler/images/CentOS5.1-xen-x86_64/vmlinuz
use virt-manager or reconnect with virsh console koan2
Koanのupdateの影響で--virtnameオプションが--virt-nameとオプション名が変わってる事に注意して下さい。
インストールが終わったらlsコマンドで確認です。
client # ls -l /iscsi/xen/koan2-disk0 
-rwxr-xr-x 1 root root 5368709121 Jan  4 19:13 /iscsi/xen/koan2-disk0
ちゃんと/iscsi/xen以下にイメージファイルが出来ました。

これから更に発展させてDSASのようなネットワークブートするイメージの管理をCobblerを使って実現とかしてみたいよね、とか話していたらmizzyさんにStateless Linuxを教えてもらいました。
どっちにしろinitrdとかイメージとかを自分で作ってかなきゃいけないので、もすこし色々やってみようと思います。

Posted by Yappo at 20:12 | Comments (0) | TrackBack

2007年12月31日

CodeReposへのコミットをリアルタイムに通知する仕組みあります

commit-ping/SITEINFO - CodeRepos::Share - Trac

CodeReposにcommitされるとこのページの Commit Ping Servers 以下にかかれているURLに対してコミットの情報がPOSTされる仕組みです。
yamlというパラメータ名でYAML形式に変換されたコミットデータがPOSTされます。
ということでアナウンスしてないけど、こんな仕組みが有ります。

svnのcommit hookを使って、Commit Ping Servers以下に書かれているURLに対してコミット時のメタデータをPOSTで送信します。
POSTする時に詰まると嫌なのでTheSchwartzを使って非同期的に処理しています。

是非面白いことをやってくださいー

Posted by Yappo at 23:22 | Comments (0) | TrackBack

2007年12月25日

GoogleのMapReduceをいまさら妄想した

ブームとかそういうのはあんまり関係無いけど、MapReduceについての妄想だけしてみた。

主要コンポーネント

MapReduceには大体6つのパーツから構成される。

clientshellから叩かれるコマンド的な何か
manager各種 worker を管理する。といっても投げっぱなしで結果がいつまでも帰ってこなかったらworkerを捨てるだけ。同じjobを複数のworkerに投げてる。
map workermapの処理
combinermapの直後に実行出来るreduceのような物、無くても構わない、出力はmapと同じ?
shuffle(Group by Key)map workerから帰って来たkey/valueを集約する
reduce workerreduceの処理
fs分散システムに対応したfsと、local disk

処理内容

mapに対しては任意のデータが与えられる。 mapはkeyとvalueからなる大量のデータを戻す。 shuffleにて、全てのmapのkeyをまとめあげて、keyごとにreduce workerにkeyとvalue listを渡す。 reduceは、受け取ったkey/value listを処理する。

key/valueなデータに特化したPlaggerってことで間違いないのかなぁ? mapperで大量のデータから必要な物をフィルタリング(Subscription,Aggregator)して、reducerで実際の処理(Filter,Publish,Notify)を行うというPlaggerみたいな感じ。

全てのmapやreduceに大しての各workerの仕事量は平均的になる様にバランス良く配置する。 多分、mapやreduceの直前で、それぞれのjobの大きさを計測してmanagerに渡したりしてるのかな。

shuffuleなんかはBig Tableとか使ってるのかもしれんね。 それか集計処理自体MapReduce使ってたり?

map workerの処理が全て終わったら reduce worker が走り出す。 これは、あるいみ無駄な気もするからmap workerが終わるのを待たずにreduce worker走らせてるだろうなぁ。(どうもそうでもないらしい。) mapとshuffuleは同時に処理出来るけど、reduceは他と一緒に処理出来ないそうな。key/value単位で処理するというMapReduceの設計的な制約かな? map,reduceが終わりそうになったら、まだ終わってないworkerのjobをそのまま空いてるwokerに投げて速く終わったworkerの方のresultを採用する事で、途中でworkerがコケても泣かないですむ。

mapとreduceの粒度は細かくした方がよい。 mapperでserialize、reducerでdeserialize。 mapだけ繰り返し呼びたい時はreduceからmapを呼び出す。

オレオレ実装するとしたら

この仕組み自体は対した事無くて、肝は大量のデータを、たくさんのmap workerやreduce workerへjobを投げたりresultを受け取る仕組みとshuffleする処理にある。 ちゃちいものだったらDanga::Socketとかで実装出来るレベルっぽいな。 もちろんGFSも肝だけど、memcachedとかでとりあえずいい気がする。(可用性おいとくという事) というかMapReduce自体もGearmanで構成出来たりしね?

実際問題としてオレオレでMapReduce作る時に考える事は、データとコードを各worker serverに送る仕組みを真っ先に考えなければいけない。 単純にjobを分散出来た所で、それはMQとかに毛が生えた程度の面白さしかないから、分散ストレージ的な物もセットにしないとオレオレMapReduceもどきとは言えないだろうけど、memcachedとか使えば解決するよね?よね?

CPANにMapReduceってモジュールが有ったんだけど、何故か削除されてる。。。backpanには残ってる。

もっとも忘れてはならないMapReduceの肝は、1 serverで並列処理をしてCPUがmulti coreしてる恩恵を受ける為に有るのではなく、大量のworkerを使う事によって大量のメモリを利用したり、大量のdiskを使う事によるi/o負荷を分散させる事に意味が有る。 それなんで、WebからMapReduce使う用な事はないのかね?

でも少数serverでMapReduceやったって良いじゃないか!

Posted by Yappo at 21:31 | Comments (1) | TrackBack

2007年12月10日

PowerEdge SC440をQuad Core + 8GBメモリで動かす

はてなのnaoyaさんの日記でQuad CPUでxenを動かしてるという事が書いてあったので、自宅でもはてなのサービスをまねた構成をしたくなったので人柱やってみました。
タイトルの通り、1万5千円で買ったSC440をDELL公式のスペックよりもオーバースペックな事をして動かしました。

まずは、メモリから。
ミラクルリナックスの中の人曰くマザーボードの仕様的には8Gまでいけて、8Gちゃんと認識したという事で、以前から買い漁ってたTranscendの1GB DDR2 667MH ECC メモリの 2GB 番の TS256MLQ72V6U 4枚買って来て刺した所 BIOSでは8G認識してるのにOS上げたら3.5Gにも満たなかった、よく考えて64bit番のCentOS入れたら無事8G認識しました。

次はCPU、SC440はXEON 3040 というFSBが1066MHzのCPUが刺さるので、同じFSBの4コアCPUのQ6600をさっき買ってきたら普通に認識して/proc/cpuinfo的にも4CPUの扱いになりました。
ただ、購入したSC440はファン無しのヒートシンクなしマシンなので、調子に乗ると大変な事になりそうで恐い。

そういえば、自宅を整理してちゃんとPowerEdgeを棚に載せました。
PE_SC440_1.jpg
PE_SC440_2.jpg
PE_SC440_3.jpg
PE_SC440_4.jpg

今時のWEBエンジニアは、このくらいの環境を自宅に置いとかないとだめだと思う。

併せて読みたい:お家NOC

インテル Core 2 Quad Q6600 2.40GHz BOX BX80562Q6600
インテル
売り上げランキング: 8565
おすすめ度の平均: 5.0
5 なかなか爆速です。

Posted by Yappo at 00:13 | Comments (4) | TrackBack

2007年12月07日

Tracで自分の追いかけたいディレクトリの変更ログだけを簡単に取り出す為の3個の手順

リポジトリへだんだんと全体のcommit流量が増えて来ると自分の突っ込んだプロジェクトに誰かがpatchを書いても気づかない事が出て来ます。
例えばCodeReposなんかがそうで、困っていた訳です。

さっき知ったんですが、tracは各ディレクトリ毎のコミットログをRSSで出せるので、これを活用して目的を達成します。
具体的にはtracのtemplateを少し追加するとRSS Auto Discoveryできるようになるので、まずはAuto Discovery出来るようにしました。

次は、誰がどのプロジェクトに関わってるかをまとめる訳ですが、これはXOXOというMicroformatsが使えるので、各コミッタページにXOXOで自分のプロジェクトディレクトリへのリンク集を書きます。
自分の場合はhttp://coderepos.org/share/wiki/Committers/yappoこんな感じです。
Tracに生HTMLを書かなければいけないのですが

{{{
#!html
<ul class="xoxo">
 <li><a href="http://coderepos.org/share/browser/lang/perl/Acme-Jyogakusei">Acme::Jogakusei</a></li>
 <li><a href="http://coderepos.org/share/browser/lang/perl/Acme-tsundere">Acme::tsundere</a></li>
 <li><a href="http://coderepos.org/share/browser/lang/perl/Class-Component">Class::Component</a></li>
 <li><a href="http://coderepos.org/share/browser/lang/perl/dan">dan</a></li>
</ui>
}}}
こうする事で生HTMLがかけました。

さぁ準備は整いました、あとはfeedをまとめるだけです。
これはもうPlaggerという優秀な裏ソフトがあるので活用しない手は無いです。
configはhttp://coderepos.org/share/browser/config/plagger/coderepos-commiter-smartfeeds.yamlこんな感じでおkでしょう。
出来上がったFeedはhttp://tech.yappo.jp/coderepos-yappo.xmlにあります。

ね、簡単でしょう?

Posted by Yappo at 16:13 | Comments (0) | TrackBack

2007年10月25日

DELL PowerEdge860届いた

ちょっとまえに投げ売りしてて注文したのがさっき届いた。
IMG_2681.jpg

Xeon 3060 2.40GHz/4M L2 cache
512M ECC memory
HDD 160G
これで7万円切ってた!!安過ぎる!
IMG_2683.jpg

メモリ512じゃ全然足りないので、1Gメモリ4本刺して使う事にした。4本でも22,000円くらいしかしない。
IMG_2686.jpg
あと、HDDは2個目も簡単に付けられそうなので、安い大容量HDDもくっつけておくつもり。500Gで11,000円くらいみたい。
IMG_2682.jpg

約10万円で
Xeon 3060 2.40GHz/4M L2 cache
4G ECC memory
HDD 160G + 500G
な1Uサーバが出来てしまった。DELLすごいよDELL

実際はラックレールマウント17,000円と記念にフロントベゼル3,000円買ったけどね。あと送料5,000円も追加。
それでも安いけど。

デフォルトでついてるメモリがhynix性でちょっと前に大人買いしたSC440と同じ物だったので、SC440に512Mメモリ二枚刺しして3Gで使えるな。
SC440は1Gメモリ4枚刺すとちょっと損した気になるので3Gくらいがちょうどいい。

しかしメインのappサーバよりもハイスペックになってしまうので、アプリケーション構成をどう変えるか悩む。
基本dmaki productsでクロウラーやれば良いのかな?

Posted by Yappo at 15:02 | Comments (2) | TrackBack

2007年10月04日

はてブのエントリページに出て来るクリッピングサイトを消してくれるグリモン書いた

みなさんは、はてなブックマークの「このエントリーを含む日記」をクリックして何か言及があるかと思ったら、クリッピングサイトで特に言及がなかった経験はありませんか?
また、自分のエントリに「このエントリーを含む日記」が付いてて、よく考えたら特定数以上のusersが付いたエントリを自動収集してる日記だったりしてがっかりしませんでしたか?

このはてブクリッピングサイトリムーバは、そんな貴方のお悩みを解決してくれる優れたuserscriptです。
このユーザースクリプトを入れるだけで、これらクリッピングサイトがエントリリスト画面から無くなってしまいます。

hatebu clipping site removerを入れたときのキャプチャ
hatebuclippingsiteremover.png

ちなみに消してるサイトは、ざっくり見てクリッピングサイトっぽいのだけをピックアップしてるので、間違ってる可能性もあります。
最初はsplog removerとかいう過激な名前だったけど、ちょっとやり過ぎなので名前変えました。
ダウンロードはhttp://svn.coderepos.org/share/lang/javascript/userscripts/hatebuclippingsiteremover.user.jsから

XPathの練習かねて作っただけだけど

Posted by Yappo at 23:55 | Comments (0) | TrackBack

2007年09月17日

第2回モバイル勉強会で発表して来ました

モバイルがテーマなので、今回は技術よりの話はしてませんが

  • ThirdForce普及の話
  • メールに件名入ってないの話
  • itkz係数について
  • GopherのPR
  • CodeReposのアピール

をテーマに発表して来ました。

取り急ぎDanさんメソッドで資料を上げときました。
若干修正済。
http://tech.yappo.jp/docs/mobaben2/

ustreamで配信されていてhttp://ustream.tv/channel/mobabenにて録画したアーカイブを視聴出来るようです。

Posted by Yappo at 18:50 | Comments (11) | TrackBack

2007年09月11日

CodeReposのircチャンネルとOhlohの件

ちゃんと告知してなかったのですが、CodeReposのircチャンネル作りました。
普通に #coderepos@freenode です。
codereposbotが常駐していてtimelineをnoticeしてくれます。

typesterさんの提案でOhlohにも登録しときました。
CodeRepos::Share - Ohloh

最初はPerlだけか?と思われ気味でしたが、現在は7言語のディレクトリがあります。
どしどし参加してくだしあ

Posted by Yappo at 22:48 | Comments (0) | TrackBack

2007年09月08日

ITPro ChallengeのLTに出て来ました

インターネットに不自由してる旅先で、つい魔が差してLTに応募したら採用されたので話して来ました。
初の試みとしては、話してる最中の様子をustreamで配信してました、といっても自分の胸ばかり写ってたかもです。そして23viewersくらいあったようです。
内容は、ごにょごにょしたのと、今空前のブームであるGopherのGopperのPRとCodeReposの宣伝して来ました。
あと、はてなスターのTシャツを着てプレゼン中にスターのアピールをしたのに、話し終わった後naoyaさんが怒ってた気がする。
やっぱり、はてなブックマークのアピールをしなかったせいだろうか。ふしぎ!
以外とGopherネタをわかってる人がおおくてよかた。

資料はhttp://tech.yappo.jp/docs/itprochallenge/にて。
キーボードの上下左右キーで操作出来ます。
後日Youtubeとニコニコ動画でプレゼンの様子をアップロードしてくれるそうです。
また、反応リンク集は便利な、はてなブックーマークをご利用ください。

id:amachangのS6を使いました、というかLL魂の資料のコピペです><
今までS6をちゃんと見てなかったんだけど、初めて使ってみようと思ってから直に使えるのはいいっすね。
amachang++

Posted by Yappo at 12:41 | Comments (0) | TrackBack

2007年08月31日

CodeRepos - 個人レポジトリを共有しよう!計画

typesterさんのつぶやき

みんながそれぞれ作って公開してる公開レポジトリを一緒くたにしちゃいたい。参加してる全員がどのファイルもみたり変更したりできるような。

パッチ送られてくる代わりに「後で見とくからコミットしといて」とかいえたりとか、つくりかけで放置したもので他の人が興味もったら続き作ってもらうとか、メンテするのめんどくなったのだれかにやってもらうとか、突発的に誰かと一緒にプロジェクト始めたりとか、できる!
に呼応する形で共有レポジトリを作りました。
http://coderepos.org/share/

特に明確な方向性とかはきまってませんし、決まるかどうかもわかりませんがtypesterさんのつぶやきを現在の方向性という事にしておきますか。
昨日作ったばかりで、今はディレクトリ構成どうしようかとかそういう事をircとかtwitterとかで話し合っているので、ディレクトリ配置が変わっちゃったりするかもですが、落ち着いてきたら配置も固定になると思います。

現在commitしてあるコードはperlの物だらけでperl専用?とかの疑問も出てましたが、どんな言語とか問わずcommitしちゃって問題ないです。
言語とかのレベルを越えて、以前流行ったdot-file公開ブームのようにdot-fileとかplaggerとかのsoftのconfigファイルの共有が出来たら面白そうです。

CodeReposに登録されてるファイルにパッチ書きたくなったり、CodeReposに自分のソースを放流したくなった方はhttp://coderepos.org/share/に記載されてる連絡先までhtpasswdで作ったファイルの中身を送って下さい。

Posted by Yappo at 19:19 | Comments (0) | TrackBack

2007年06月01日

VirtueDesktops の 0.54 Beta 3 (339) が酷すぎた件

Betaリリースなんだから煩いぞ!とお叱りがあるのは分かりますが、ああ、あと自分が使ってるソフトの組み合わせが悪いって事の検証もしてない、する気力も消えた。。
ググっても数件しか、この話題が見つからなかったから書いとく。

初代MacBook上のOS 10.4.9の上でVirtueDesktops の 0.54 Beta 3 (339) を使っていたんですよ。
それは置いといて、ここ最近は1日辺りに500M以上も空きディスクが減ってったわけですよね。
最初は仮想メモリにでも使ってんのかなとか楽観的に見てたんですが、この数日は余計なでかめなファイルを消して行ってギガバイト単位で空き容量をせっせこ作ってたわけです。

昨日、ついに異変に気づきdf -iとかしてたら秒単位でinodeが5づつくらい減ってるんです。
しかも数百KBも要領を消費しながら!
これは明らかに可笑しいので、ここ最近入れたソフトを調べ、VirtueDesktopsを終了させたらディスク消費が収まったので犯人が解ったのです。

で、ググって見て何にディスクを使っているかというとLogファイルらしく

$ ls -l ~/Library/Logs/VirtueDesktops.log 
-rw-r--r-- 1 my my 12082867527 Jun 1 13:15 ~/Library/Logs/VirtueDesktops.log
とかいう酷い事になってました。
このログの中身をheadして見ると5月16日から記録が始まっているので、多分VirtueDesktopを最新のβ版に入れ替えた後からロギングしてるようです。
βなのでデバグ出力かな?

ファイナルリリースでてたみたいだけど、もうこのバージョンの使うの辞めて0.52 (138)を使ってLogも消して奇麗さっぱり忘れてしまおう。

Posted by Yappo at 13:35 | Comments (13) | TrackBack

2007年04月02日

YAPC::Asia 2007TOKYOに出て来ます。

初参戦で、3個発表する事になりました。

長めの内容2本LTです。

頑張って資料作ります。

なんあk昨日の記憶があまりない。ジャガイモの芽が出て来たよ!春っていいですね!

Posted by Yappo at 10:00 | Comments (0) | TrackBack

2006年12月21日

IEがWeb2.0に対応していなかった件

既出ネタかどうか分からないけど、iframe name tagsでググっても情報でて無いので書いておきます。
特定のタグやname属性をHTML中に記載するとIEのCtl-Fでのページ内検索やプリント機能が使えなくなります。

詳細は以下の通り。

iframeタグを使用したHTML内で、name属性が使えるタグのname属性にtagsを指定すると、IE6ではページ内検索を実行したときとページプリントを行ったとき(プレビューだけでも化)にエラーダイアログが表示されてしまい、検索や印刷が出来ません。
IE7で直ってるかと思いきや検索だけは出来ません。
エラーコードがIE6とIE7で違うため、バッファオーバーフロー的な何かがIEの中で起きていると思われます。

再現する最小ソースは

<iframe></iframe><img name="tags">
これだけで再現しました。
サンプルページは下記の通り。
imgタグ
inputタグ
aタグ

なんでこんなんで駄目になるのかは分かりませんが、マイクロソフトはtagを用いたWeb2.0的な物がお嫌いなんでしょうか。
DOM操作とかでiframeを構築して行ったらどうなるかは試していません。
あと、javascript無効にするとどういう挙動になるとかも見てません。


どうにかしてIEのみでしか見れないページを作れば、印刷不可能なページの作成も物理的に可能そうです。

追記:12/22
id:holidaysの人が詳細を追いかけてくれました。
holidays-l開発ブログ - IEで印刷できないページ

としてみたところ、document.all.tagsというnativeな関数を呼び出していました。(document.all.tags = document.getElementsByTagName?)
nameで上書き出来る場所に重要なのを置いていたと言う事なんすかね。
iframeがあっても無くても関係ないみたいです。
iframeを無くすと印刷できませんが検索は出来る様になります。で、iframeを入れると何故か検索が出来なくなると。
やっぱり不思議です。
name使わないでidというのも諸事情で却下す。

Posted by Yappo at 23:09 | Comments (2) | TrackBack

2006年11月20日

the spam退治の能率を100倍うpする方法

最近あり得ないくらいにspamが来てて、過去に行ったアジア全て(台湾、韓国、中国)からのip接続のblockも意味なくなってしまって途方に暮れたのですが
初心に返ってSpammAssassinを真面目に使う事を思いついた。

家はmew使ってて+spam/にspamに振り分けられたメール、+spam/spam/にspamから漏れたメール、+spam/ham/に誤爆したメールを振り分ける様にしてるんだけど。
学習させるたびにコマンドうって、学習させたメールを+trash/にやるのがだるくて使ってなかった。

そこで最近学習した、面倒い事はちょっとしたツールで対処ってのをやった。

$ alias spaml="sa-learn --spam $MAILDIR/spam/spam;rm $MAILDIR/*"
これだけ作ったんだけど、spamlってやれば+spam/spam行きのメールをspam扱いにしてrmしてくれる。
今の所誤爆もないのでhamもやっていない。

これだけじゃ、まだだめでMewの操作も簡潔にしないと漏れたspamが100件とかきたら辛いのでemcasのマクロを登録。
普段だとosp<TAB>s<TAB><RET>な感じでキーを打っているのでこれも楽にしたい。
.emacsをにちょっと追加

(fset 'my-mew-set-spam
"ospam/spam\C-m")
(define-key mew-summary-mode-map "zz" 'my-mew-set-spam)
これでzzで振り分けられる様になった。

意外にspamの認識力が高くなって来て、spamフォルダに毎日500くらい自動的に行ってる。
spam退治が100倍以上効率うpした!

ので、能率が100倍うpした。

Posted by Yappo at 22:15 | Comments (0) | TrackBack

2006年11月15日

悪のりで学ぶsvnadmin/trac入門実用編

とある平和なある週末に事件は起こった
xx:14 ([aopy]+) stfuawsc汚染なコードをciってまった

xx:14 (A) ちょ
xx:14 (B) ww
xx:14 (C) www
xx:14 (D) stfuawsc
xx:14 {[ainOS]+} パネラーディスカッション
という事で、直近のコミットした内容をこの世から抹消しなければならなくなった。
しかもtrac上のデータもあわせて..!
消したいリビジョンは100である。

svnのデータを消す

コマンドだけで直前のコミットを取り消せないものかと調べたが、出来ないという事が分かった。
ちょっと冷静になって、svnadmin dumpとsvnadmin loadの組み合わせで何とか出来ないか?と考え
$ svnadmin dump /svn/public > /tmp/public.dump
して該当データを探してみた
Revision-number: 100
Prop-content-length: 112
Content-length: 112

ここからデータ

最後のほうに、該当するデータっぽいのを発見出来た、Revision-numberも100と書いてあるので、当たりっぽい。
Content-lengthとかもあって大分親切。なんかmailのフォーマットぽい。

って事で、このRevision-number: 100の行からファイル末尾まで削除して

$ cat /tmp/public.dump | svnadmin load /svn/public.new
$ mv /svn/public /svn/public.old
$ mv /svn/public.new /svn/public
した。
そして、手元のcoしたディレクトリでsvn upしてみたら
Reference to non-existent revision 100 in filesystem '/svn/public/db'
と言われたお><
落ち着いて
$ svn up -r 99
したら、エラーが出なくなった。

これでsvnの証拠隠滅は完了した。

tracのデータのつじつまあわせ

気を良くしてtracにアクセスしたら、見た事のないエラーが出てびっくりした。
そりゃそうだ、リポジトリの中とtacの中のデータが不整合してるからだ。

tracはsqliteつかってるので

$ sqlite3 /trac/public/db
してsqlを使える状態にして、あれこれ調べた。
で、大体消す場所を把握したので
sqlite> delete from revision where rev = 100;
と打った、しかしtracがまだ怒ってる!
もう少しデータを漁って、ようやく別の消すデータを発見
sqlite> delete from node_change where rev=100;
これでどうだ!

見事、問題のコミットは帳消しに出来ましたとさ。
めでたBoofyめでたBoofy

追記:
svnのいらないリビジョンはsvnadmin dump -r 0:99 | svnadmin load とかで消せて。
trac-admin resync で同期が取れるそうです。

みなさま突っ込みありがとうございます。

Posted by Yappo at 23:32 | Comments (2) | TrackBack

svk startup memo

生のsvnを使っていて良いのは中学生までなのでsvkを始めました。
といってもmacbookの方にはsvkを入れてたんだけど、あまり使っていなかったのでメインの開発環境にsvkを入れました。

ありきたりでつまらない内容ですがチラシの裏です。

install

SVN::Mirror 0.72 は subversion 1.2 以上を要求してくるので、手元の環境で使えずに0.71を入れました。
LANG=jaな環境でinstallするとtestこけるのでLANG=C cpanな感じでinstallです。

そしてinstall SVKなのですが、06keyword.tでなんかこけるのでforce installです。(SVK 1.08)
こけてる内容もクリティカルじゃ無いっぽいので無視です。
なんかsvk-devにも報告あがってるみたいだけど、よく読んでない。

setup

$ svk mirror http://svn.yappo.jp/repos/public/ //mirror/public
$ svk sync //mirror/public
$ svk cp //mirror/public //public
教科書的にミラーを作ってローカルブランチ作成です。

import to local

importしたいファイルのカレントディレクトリで
$ svk import //public//proj/trunk -m 'proj import'
してがしがしimportしました。
ローカルに連続でimportしてってもいいし、一個importするたびにほんとのリポジトリにうpしてってもいいのかな。
一個一個やってったほうが奇麗かも。理由はあとで。

commit to remote

smerge

ローカルブランチのcommitをリモートの本家リポジトリに反映します
$ svk smerge //public //mirror/public -m 'commit message'
これで、全ての変更内容がhttp://svn.yappo.jp/repos/public/に反映されます。
全部いっぺんがいやなら
$ svk smerge //public/Soozy/trunk //mirror/public/Soozy/trunk
でもいけるはず。まだ試してないけど。
これだと、手元で細かくcommitしてるのに本家は荒くなっちゃうので
$ svk smerge -l //public //mirror/public
として、ローカルのコミットログをまとめて送れるようになります。
いったんコミットメッセージをエディタに流し込んでくれる形なので、任意な形でコメントが書けます。
これでも、diffの内容としては荒いので
$ svk smerge -I //public //mirror/public
として、ローカルの1コミット毎の内容をそのまま本家に転送します。
ローカルで上げたリビジョンの数だけ本家もリビジョン上がる感じです。
これやった瞬間に本家に全部コミットされるので注意です。

で、importしたときにsvk smerge -Iとかしちゃうと、2回分のログが発生するのでimportしたらオプション無しのsvk smergeして2回分を1回にまとめちゃうと奇麗かなぁと思いました。
http://trac.yappo.jp/trac/changeset/178みたいな感じです。
纏めないとhttp://trac.yappo.jp/trac/changeset/181http://trac.yappo.jp/trac/changeset/182のように2回に分かれます。

どうでもいいっすね。

svk push

カレントディレクトリのリポジトリをsmergeするって感じすかね。
ここでは
$ svk co //public ./public
cd ./public
したものとして書いてます。
ローカルの1コミットを纏めてコミットする
$ svk push -l

バラバラでコミットする
$ svk push

svkが付けるコメント

特にオプションつけないでsmerge/pushすると
r196@haruna: ko | 2006-11-15 19:51:20 +0900
みたいなコメントが自動的に付与されますが、これを消したい場合は--verbatimオプションをpush/smerge時に付ければ消えます。

よく考えれば、普通はsvk pushを使うね。
こんかいはimportしまくったからsmergeしただけか。

svk pull

svk co //publicでチェックアウトした先のディレクトリでsvk pullすると、本家リポジトリが変更されてたら、//mirror/publicもupdateした上で//publicもupdateして、手元のディレクトリの内容もupdateしてくれた。
pullした時のmirror/local/currentdirを通したコリジョンとかの扱いはよくわかってない。

push/smergeする前に-Cオプションで変更点を確認しないと高校に入れないので注意。

以上、チラシの裏Boofy

Posted by Yappo at 21:15 | Comments (0) | TrackBack

複数のsvnリポジトリを一つにまとめる方法

うちのsvnリポジトリは、trac等で公開をする前までは、各コンポーネント毎にリポジトリを作るという非効率な管理をしていました。
そろそろ嫌になって来たので、これを全部公開用にまとめようと思い、helpみながら頑張りました。

要件的には、リビジョン番号が変わっても良いから、とにかくlogを含めてインポートしたい!
という感じです。

最初はsvkとか使わなきゃだめなのかなぁ、とか思ってたのですがsvnadminだけで願いが叶いました。
dumpとloadを使います。
loadする時はオプション無しでloadしてしまうと、dump前のファイルパスにデータをぶっ込んでくれちゃうので、trunkとかが混ざってカオスになっちゃいました。
そこで--parent-dirオプションを使って、どのパスにloadするかを明示的に指定してloadします。
--parent-dirで指定するパスは、読み込ませる側のリポジトリ内に予めmkdirしておく必要が有ります。
/svn/Acme-Monta のリポジトリを /svn/public_repos に入れたい場合は

$ svn mkdir -m 'create import dir' file:///svn/public_repos/Acme-Monta
$ svnadmin dump /svn/Acme-Monta | svnadmin load --parent-dir Acme-Monta
のように作業します。
commit日時は引き継がれるので、リビジョン番号と日時の並びが変になりますが気にしない感じで。
影響でtracの最近のtimeline消えた!

これで、作業環境がすっきりしました^^
あとはsvkを本格的につかいまする。

それsvnadminでできるよ
それsvn

Posted by Yappo at 18:44 | Comments (0) | TrackBack

2006年09月28日

価格.com API JSONPと、JavaScriptテンプレートキットの組み合わせ

価格.comのAPIが話題になってますが、APIの結果をJSONPで履いてくれる価格.com API JSONPが公開されていたので、先日のテンプレートの奴と組み合わせて物を作りました。
本来なら価格.com本体でJSONP吐いてもいいんですけどねぇ。。。ケチ。。。

http://tech.yappo.jp/demo/kakaku/
JSONPだけでAjaxの動的検索っぽい事をしています。
作り方は、とても簡単なのでソースを読んでみるといいと思います。

もっともっと単純な方法は

<div class="kakaku">
<table>
<tr>
<td><a class="[% $ItemPageUrl | attr 'set' 'href' %]" target="_new"><img class="[% $ImageUrl | attr 'set' 'src'%]" /></a></td>
<td>
<table>
<tr>
<td>製品名</td>
<td><div class="ProductID"></div><a class="[% $ProductName | inner %][% $ItemPageUrl | attr 'set' 'href' %]" target="_new"></a></td>
</tr>
<tr>
<td>カテゴリ</td>
<td><span class="CategoryName"></span>(<span class="PvRanking"></span>位)</td>
</tr>
<tr>
<td>メーカー</td>
<td class="MakerName"></td>
</tr>
<tr>
<td>最安値</td>
<td class="[% cat $LowestPrice '円' | inner %]"></td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<script type="text/javascript" charset="euc-jp" src="./cjtk.js"></script>
<script type="text/javascript">
var cjtk;
var config = {
classname: 'kakaku',
foreach: true,
url: 'http://jsonp.yatena.com/' + encodeURI('ipod'),
};
cjtk = new Cjtk(config);
cjtk.process();
function kakaku_ws(obj){
cjtk.callback(obj.Item);
}
</script>
のように記述すれば下記の様に表示出来ます。
http://tech.yappo.jp/demo/kakaku/body.html
この方法だとキーワードが固定になるけど、使い出はあるかもです。
これはipodで検索する様になってますが、アップルにしたければ下のJavaScriptの部分を
    url: 'http://jsonp.yatena.com/' + encodeURI('アップル'),
にしてください。

ツールがそろってくるとマッシュうpも楽になりますな。

という訳で、テンプレートキットの販促活動でした。

Posted by Yappo at 19:39 | Comments (2) | TrackBack

2006年09月26日

CJTK - JSONPとJavaScriptを使ったテンプレートキット作った

JSONPなどでデータを取得して、HTML中の任意なAttributeにマクロを埋むタイプのテンプレートキットを作りました。
別にJSONPじゃなくても、staticもデータ構造を定義する事も出来るし、Ajaxサポート書けばAjax経由でデータを取得できます。
マクロ展開はDOM探索で色々処理をしています。 Model = JSONP 、 View = DOM って感じかも。

他にもJKL.Hinaや、JSmartyなどがあります、大きな違いは専用構文を利用しないでテンプレート展開が出来たりと、かなりシンプルです。
他の特徴は
・DOM操作のみでテンプレート展開
・JSONP対応
・テンプレート用のデータ領域を用意する事無く、HTMLに直接テンプレートを記入出来る
・データ展開先を設定不要。class要素などからテンプレートエンジンが、自動的に展開先を選択する
・DOM操作を基本としてる為、if/foreach等のスコープが実際のHTML構造と連動していて直感的
・DOM要素の属性を柔軟にカスタマイズできる
・フィルタチェイン
・フィルタの拡張が可能
などなどです。

デモ用のサンプルはhttp://tech.yappo.jp/demo/simplemacro/
tracはhttp://trac.yappo.jp/trac/browser/javascript/cjtk/trunk
svnは

svn co http://svn.yappo.jp/repos/public/javascript/cjtk/trunk

チュートリアル


simple injection

マクロと言っても、簡単に使う分には専用の言語らしき物は見えません。
たとえばdel.icio.usのJSONPだと(http://del.icio.us/feeds/json/yappo?callback=delisious.callback)

new Array(
{
u: url,
d: タイトル,
n: コメント,
t: new Array(tag1, tag2)
},
{
u: url,
d: タイトル,
n: コメント,
t: new Array(tag1, tag2)
}
);
の様な構造になっているので、これを簡単に展開したい場合には
<javascript>
var config = {
classname: 'delicious', // class属性がdeliciousのDOM要素をテンプレートとして使用する
foreach: true, // 上記で取得したDOM要素を元にして、JSONPで取得じた全レコード分を展開
url: 'http://del.icio.us/feeds/json/yappo?callback=delisious.callback', // JSONPのURL
};
var delisious = new Cjtk(config);
delisious.process();
</javascript>
<div class="delicious">
<div class="u">URL:</div>
<div class="d">タイトル:</div>

</div>

とかけば、「URL:」や「タイトル:」の後に、それぞれURLとタイトルが挿入されます。
と、単純なデータ/展開方法であれば非常に完結にテンプレートを組めます。

attribute injection


さて、単純なのは良いのですが、これではリンクを張ることが出来ません。
そこで、マクロ構文が出て来ます。
リンクを張るためには、HTMLを次のように変更します。
<div class="delicious">
<div>URL:<a class="[% $u | attr 'set' 'href' %][% $u | inner %]</a></div>
<div>タイトル:<a class="[% $u | attr 'set' 'href' %][% $d | inner %]</a></div>

</div>

これで、URLとタイトルそれぞれにURLへのリンクが張られます。
このマクロの構文は微妙にTTっぽい気もしますが、UNIXのpipeの概念の方が近いです。
たとえば
<div class="[% 'D' | $d %][% 'A' | cat 'B' 'C' | cat $d | inner %]"></div>
なんて事が書けますが、これを分りやすくコメントを付けると
<div class="[% 
'D' | $d # $dという変数に文字列'D'をセット
%][%
'A' | # 文字列'A'を次の処理へ転送
cat 'B' 'C' | # 文字列'A', 'B', 'C'を順番に結合して、文字列'ABC'を作成して次の処理へ転送
cat $d | # 文字列'ABC'と変数$dの中の文字列'D'を結合して、文字列'ABCD'を作成して次の処理へ転送
inner # 転送されて来た文字列'ABCD'を、現在のDOM要素の子TextNodeとして追加する
%]"></div>
と、こんな感じになります(実際は#のコメントは書けません)。

if / unless


次に条件によって要素を表示したく無い場合があるでしょう。
たとえばdel.icio.usのコメント何かがそれにあたります。
そんな場合はifやunlessが使えます。
<div class="delicious">
<div class="u">URL:</div>

<div class="d">タイトル:</div>
<div class="[% $n | if %]"><div class="n">コメント:</div></div>
</div>

ifはパイプの前の処理結果があれば(もしくは0でなければ)子要素を表示します。
unlessは逆の条件です。
もしifの条件に一致すれば
<div class="delicious">
<div class="u">URL:</div>

<div class="d">タイトル:</div>
<div class="n">コメント:</div>
</div>

と表示され、一致しなければ
<div class="delicious">
<div class="u">URL:</div>

<div class="d">タイトル:</div>
</div>

となります、defaultではif/unless文のあるDOM要素は削除されます。
もし削除したくない場合にはBKっぽく
<div class="delicious">
<div class="u">URL:</div>
<div class="d">タイトル:</div>

<div class="[% $n | if '1' %][% $n | inner %]">コメント:</div>
</div>

と書くことも可能です。
ifのあとに1を加える事で、ifがあるDOM要素を削除しません。

foreach


del.icio.usの場合はtag要素が配列として渡されます。
配列要素を展開する場合にはforeachが使えます。
<div class="delicious">
<div class="u">URL:</div>

<div class="d">タイトル:</div>
<ul class="[% $t | foreach 'tag' '1' %]">
<li><a href="http://del.icio.us/tag/" class="[% $tag.v | attr 'append' 'href' %][% $tag.v | inner %]"></a></li>
</ul>

</div>

ulというDOM要素を削除しないままtagの数だけliタグを展開します。
attr 'append'することで、aタグ中のhref="http://del.icio.us/tag/"を消さずに、http://del.icio.us/tag/tagの様なリンクを張るようになってます。

応用


レコードIDが確定してる場合

次のようなレコードのIDが固定的なデータの場合にはforeachオプションでテンプレート展開をせずに、レコードIDを指定したテンプレート構築が出来ます。
レコードIDはdefaultではtitle属性に入れます。
例えば

var json = {
hatena: {
url: 'http://www.hatena.ne.jp/',
cto: 'naoya'
},
mixi: {
url: 'http://www.mixi.co.jp/',
cto: 'Boofy'
}
};
なデータの時には
<javascript>
var config = {
classname: 'mixna', // class属性がmixnaのDOM要素をテンプレートとして使用する
params: json // 入力データをJSONをやめてローカルなデータを使う
};
var c = new Cjtk(config);
c.process();
</javascript>
<div class="mixna" title="hatena">

はてな
<div class="url"></div>
<div class="cto"></div>
</div>
<div class="mixna" title="mixi">
みくしい
<div class="url"></div>

<div class="cto"></div>
</div>

という記述が可能です。

ちなみにこの例ではJSONPを使っていませんが、JSONPを使用する場合には該当するDOMのtitleからレコードIDを全てかき集めてJSONPでリクエストする時にクエリパラメータとして送信します。
今回の例だと

json.js?id=hatena;mixi
といった形でクエリを自動的に構成する事が出来ます。
defaultのセパレータは;ですが変更出来ます。

構文拡張

プラグイン機構を使って、マクロを追加出来ます。

Cjtk.register_function(拡張名, function(context, obj, func, stdin, args){});
と拡張を登録する事によって
[% 拡張名.マクロ名 %]
という風に追加したマクロが使えます。
基本のマクロも、これを使って実装しています。

マクロシンタックス

全てのマクロは|(pipe)で処理をつなげる事が出来ます。
マクロの戻り値が次のマクロの入力に使われます。
例外としてマクロの最後に$valueのような変数が指定されていた場合は、変数に文字列が代入されます。

[% 'test' | lc | replace 'T' 'P' | $value %]
だったら、$valueに'PESP'が入ります。

if

分岐条件です。

if 

直前のマクロの結果が真なら、現在のDOM要素以下を表示し、偽なら現在のDOM要素以下を削除します。
偽の場合は、if文以降のマクロは処理しません。
[% '0' | if %] # 条件成立せず
[% '' | if %] # 条件成立せず
[% 'a' | if %] # 条件成立
[% '' | if | cat 'a' | inner %] # cat以降は処理しない
[% '' | if %][% 'test' | attr 'set' 'title' %] # 'test'以降は処理しない
if文に引数を与えると、if文があるDOM要素の削除を行いません。
<div class="[% '1' | if %]">test</div>

これが
test
となるところを
<div class="[% '1' | if '1' %]">test</div>

<div>test</div>
となる

unless

ifの真偽の条件が逆になっただけです。


foreach

入力で与えられた配列データをforeach展開します。

foreach 展開後の変数名 
flagを与えるとifの時のように、自DOM要素の削除を行いません。

inner

子DOM要素にTextノードを作成して、入力のあった文字列を挿入します。

inner <'set|append'>
setを指定すると、子要素全てを削除してから挿入を行います。

attr

自DOM要素の指定した属性を操作します。

attr 'get|set|append' '属性名'
getを指定すると指定した属生の値を取得します。
setを指定すると、入力した値で上書きします。
appendだと追記します。


cat

文字列を結合します。
joinのような感じです。
入力値があれば入力値を第一引数としてあつかいます。

lc

lcです。

uc

ucです。

replace

javascriptのreplaceです。

ret.stdout = typeof stdin == 'string' ? stdin.replace(args<0], args[1>) : '';
こんな実装。


html

htmlエスケープさせるフィルタ。

nop

何もしません。
if文の後にnopを置くと、次のマクロにif文の出力を引き継がないのでcatつか使えるようになります。

コンフィグ

new Cjtk(config);した時に指定出来る設定は次の通り

var config= {
type: 'text/javascript', # JSONP利用時のscriptタグで仕様
charset: 'utf-8', # JSONP利用時のscriptタグで仕様 JSONPのcharsetを入れる
separator: ';', # foreach展開をしない時にレコードIDをクエリパラメータに含める際のセパレータ
foreach: false, # foreach展開をするか
ajax: false, # ajax利用するか(ajaxのコードは未実装)
start_tag: '[%', # マクロの開始タグ
end_tag: '%]', # マクロの終了タグ
macro_attribute: 'class', # マクロを入れる属性名
rowid_attribute: 'title', # レコードIDを入れる属性名
params: '', # JSONPなどを利用しない場合は、ここにデータを指定する
process_callback: function(context){} # テンプレート展開が終わった時に呼び出される関数
};


いかがでしょう?

Posted by Yappo at 13:28 | Comments (1) | TrackBack

2006年09月25日

【GPS】FOMA903iシリーズのP903iをさわって来たよ【ストリーミング】

さらっとググって見たけど情報が見当たらないので書いておきますね。
製品版とがらりと変わっちゃううかもだけど、スケジュール的に無理っぽいからほぼ確定ぽ。

肝心のメニュー周りをさわり忘れてたから、ワンセグ対応だどうだとかは知らないけどテレビは見れないっぽい。
液晶画面上部中央にGPSのアイコンがあったのでP903iはGPS対応してるはず、これもメールメニューとか見忘れてて連携がどうなるかわからん。
もしかしたら903iシリーズ全機種でGPS対応とかやってくるかもね。

基本的にiモードでのブラウジングしかしてなくって、ブラウザ的には902iとかと差はなさそう。
iモードメニューに「iモーション設定」ってのがあって、ストリーミングをどうするかってのがあったよ。
メガアプリとかで大容量ダウンロードさせるつもりらしいから、普通に全機種ストリーミング対応するかもね。

あとiチャンネルwも残ってた。

詳細は、そのうち発表されるのかなぁ。
GPSとストリーミングが全機種搭載されて公式CP以外に機能が解放されていたら、結構なサプライズになりそう。

UAは

DoCoMo/2.0 P903i(C100;TB;W24H12)
アプリダウンロード時とかまで見るの忘れた。

あーNDAとか関係ないから心配しないでね。

Posted by Yappo at 11:13 | Comments (0) | TrackBack

2006年09月24日

使用コマンドランキング

Clouder::Blogger: 使用コマンドランキング
やってみた

$ history | awk '{print $2}' | awk 'BEGIN {FS="|"} {print $1}' | sort | uniq -c | sort -r
236 fg
158 ./script/planetasp_server.pl
95 perl
67 vim
42 ls
37 lv
35 ./script/catpla_server.pl
32 ab
29 cd
28 trac-admin
27 /usr/local/apache/bin/ab
25 screen
21 perldoc
19 emacs
15 grep
14 ./script/jitensya_create.pl
12 bg
11 ~/svn/public_repos/sandbox/PlanetASP/script/planetasp_server.pl
8 cat
7 rm
。。。

fg多いのはemacsでサスペンドしまくるから。
perl多いのはいわずもがな。
vim多いのはemacsは常に立ち上げっぱなしだから。
trac-admin多いのはtracいじってたから。
ab多いのはSoozyのメモリリーク探してたから。
catalyst系多いのはPlaggerのあれ作ってたから。
jitensya_create.plはSoozyのデバグアプリ。

Posted by Yappo at 06:43 | Comments (0) | TrackBack

2006年09月21日

mod_proxy_balancerのretryの件

mod_proxy_balancerのretry : blog.nomadscafe.jp

バックエンドのサーバが十台以上あるようなところだったらいいけれど、2~3台のサービスで間をあけずにデプロイしてしまうと下手するとサービスが数秒間、全落ちになってしまう可能性がある。

ということで、普通にretryを短く(数秒)にすればいいんじゃね。

1.balancerのマネージャにアクセスして該当のサーバをいったん外す
2. httpdの停止
3. rsync
4. httpdの開始
5.balancerのマネージャにアクセスして該当サーバを付け加える

でよくね?
この一連のスクリプトをバックエンドに仕込んどく感じで。
折角のmod_proxy_balancerなんだし。

うちも作ってもらわないとな。。

Posted by Yappo at 19:33 | Comments (1) | TrackBack

2006年09月11日

Re: screen のキーバインド

naoyaグループ - naoyaの日記 - screen のキーバインド

CTRL + A が screen のメタキーに当たってる場合、シェルでカーソル先頭に持ってくときどうしてるんでしょ? シェルが vi キーバインドなのかな。
Ctrl-a + a してます。
ちゃんとタイプしないと、Ctrl-a + Ctlr-aと見なされて後ろ行っちゃうけど、そんなに不自由しない感じです。


なんて返しが出来たらかっこよかったんんだけど、シェルのCtrl-Aなんて初めて知ったよ><
行頭までカーソル戻して作業したいケースは、あんましなくて大体は行の真ん中くらいのを弄りたいから不便してなかったし、行頭持ってく時は左押しっぱで頑張ってました。
もしくはターミナル上でコピペ。

顔真っ赤にしながらman screenしちゃったよ..!

Posted by Yappo at 17:22 | Comments (0) | TrackBack

Developer Enviroments Conferenceの件

ということでDECONの受付で資料配りやって来ました。バタラBoofyTシャツ着て。
開場直後と講演直前にピークタイムが分散してて面白かったです。

折角なんで自分の環境も晒して見るテスト。
普段会社の事は書かないんだけど、問題ない範囲で書いとく。
土曜の昼間に書いた文章だけどうpるの忘れてた。

ハード

PC


・MacBook
・RedHat 9.0(会社)
家とかだとリラックス優先だからノートでソファーみたいな感じでやるんだけど
会社だとノートでの開発効率悪いんでlinuxでkterm立ち上げまくって開発して
MacBookで確認するって感じです。IEとか必須なので、そこはどうにかしてます。

ちょっと前まではWindowsノートだったんですけど、あっさりとMacにスイッチしました。
またWindowsにスイッチするハメになりそですが。。。

マウス/キーボード


特にこだわりなく、標準の機材でやってます。
ハード買えたばっかだと不慣れになるけど直ぐに慣れちゃうので。

これじゃなきゃ駄目だってのがあると非常事態に融通が利かなくなりそうで怖いので、なんでもフラットに使える気持ちで挑んでます。

ソフト

ローカル環境


・kterm
・iTerm

以上。
iTermは文字列をドラッグするのがキモイ。
結構日本語が崩れるので、もっとちゃんとした奴ほすぃ。
ktermが一番しっくりくる。

あーあとMacでalt+tabする為にWitchっての入れてます。

shell


・bash
・screen

.bashrcにちょろっと環境変数かく位で、あとはノーマルです。
screenの切り替えもCtrl-Aです。
なんかemacsの絡みがどうとかでCtrl-Tな人が多数派でしたが、自分意味分かってナス。
全然困ってないし、むしろ多用するからctlキーの横のAのがベンリす。

screenは基本的にscreen -x多用してますな。
emacs -nw -e rieceとかしてるからirc常駐しっぱなしとか。
あとは、ログインして速攻で前回の作業環境を復元出来るってのも便利かなと。
どこからログインしようがセッション復元出来るし。

editor


・emacs
・vim

emacsも特にカスタマイズはせずに最低限

(setq make-backup-files nil)
(display-time)
だけやってる感じです。
.emacsはちょっと真面目に仕込みたい今日この頃。

vimはemacsでいじりたく無いserver系のconfigとかsvn ciしたときとか、emacsあげるのがだるい時とかに使ってます。
これはどノーマル。

mixiで「eclipseとか使ってないの?」って聞かれたけど

仮想デスクトップ


linuxは8個付けてて、メール用,Yappo系用,案件別,sandoboxと用途毎に全部わけてる感じです。
MacBookの方はVirtuDesktopsで6個にわけてて、Firefox,iTerm,その他みたいにわけてる。


全体的に

コードをどこで書くか


あまりMacBookの中でコード書くという事はしない、Macで動くかどうかのデバグとかする時くらいかも。
むしろローカルにコードを持って来て開発するスタイルってのが良くわかってない。
モジュールとかなら良いけど、サービスのコードとか。
たぶんそれは誰のサービスをいじってるのかという所に違いがあるんだろうな。

リモート上の開発環境にログインして開発するってスタイルですね。

Subversion

3〜4年くらい前からつかってるはず。
6年くらい前にCVS試したけど、あり得ない程の使い勝手の悪さだったのでバージョン管理システム使わなかった。
で、Subversionがいい感じになったから導入と。

trac

plagger.orgとか他の人が入れてるのをみて、いい感じだから最近使い始めた。
timelineのfeedをplaggerで読んでPublish::Gmailで社内MLに投げる感じ。
この用途ではPublish::Gmailは使い勝手悪いので、s_nobuさんに作っていただいた奴に入れ替えたい感じ。

フレームワーク


既存の製品を使うと、どうしてもパッチを書かなきゃいけない状況になったり、そのほか運用的に面倒そうなので、あんまりCatalystとかSledgeは使う事ないだろうなぁと。
まぁ、それらをパクったの作って使ってるので、それに勝る道具はない感じではあります。
良いアイデアを誰かが実践してたら、それを吸収してくのも楽ですし。

多分フレームワークは使う物じゃなくて作る物なのかも。
!DRY。

メモ


作業用windowの後ろにいっこkterm上げといて、cat > /dev/nullして、そこにメモはっつけといてる。
すこしヤバメな情報も、ファイルに残す訳ではないから安心。
適当なデータとか捨てワンライナーとかはvim /tmp/hogeみたいなのでやる感じ。

その他


自分もカスタマイズとかしないですね。
多様な環境を触るので、ただでさえストレスが溜まる環境があるのにバリバリにdot-rcとか書いて快適にしちゃうとヤバい事になるし
面倒いしで、デフォルトが一番良いんじゃないのかなぁと思ってます。


というかconfig周りはさぼってる感はあるので、ちょっと改心しますぽ。
あーあとプレゼンの内容からインスパイアされた部分あるので、ちょろっとツール作ってみる。
おっぱいさんを便利に管理出来るようなのとか。

雷鳴ってキターーー!

Posted by Yappo at 04:11 | Comments (2) | TrackBack

2006年09月07日

用途別にapacheのプロセスを分離して最適化

Yappoの本番環境って凄く手抜きしてて、一つのhttpd.confにstaticとmod_perlとcgiとphpな環境がごちゃ混ぜになってるんですよね。
問題ないように見えるようで実はmod_perlなアプリってメモリ食いまくりだから(数十MB)、性的なコンテンツを沢山のhttpdプロセスで処理するって事が出来ないのね。
まぁそんなケースは滅多にないけど。

mod_perlは8個くらい上がってれば十分で、その分メモリに余裕を作って他の事やろうとすると、静的なコンテンツの為のhttpdが足りなくなる。
みたいなジレンマがあって、いいかげんapacheの分離作業をやりました。
分離された物にフロントのapacheがprxoyする感じで。

昔のhttpdな構成をまとめると


+---------------------------------------------+
| apache1.3(static/mod_php/mod_perl/mod_proxy)|
+---------------------------------------------+
|
+---------------+
| |
+---------------+ +-------+
| apache2.0(SVN)| | tracd |
+---------------+ +-------+

#あとも一個別に開発環境

一番上のapacheは30Mくらい物理メモリを使ってます。
まずはmod_perlを全部分離する事から始めました。
この辺の方法論についてはライブドアを参考(WEB+DB PRESSとかオープンソースマガジンの記事参考)にして
apache作る時に--target=modperlしてます。

+------------------------------------+
| apache1.3(static/mod_php/mod_proxy)|
+------------------------------------+
|
+-------------------------------------+
| | |
+--------------------+ +---------------+ +-------+
| apache1.3(mod_perl)| | apache2.0(SVN)| | tracd |
+--------------------+ +---------------+ +-------+

#あとも一個別に開発環境

これでmod_perlが分離され、上のapacheの物理メモリ使用量が10Mくらいに落ちました。
ついでに、今までさぼってたstartup.plもやや真面目に作ったので全体のメモリ効率はかなりうpしました。

ここまで来たら、まだ何かしたくなるのが人の子ってことでphpとcgiも別プロセスに飛ばしたくなりました。
--target=modphpで分離です。


+----------------------------+
| apache1.3(static/mod_proxy)|
+----------------------------+
|
+----------------------------------------------------------------+
| | | |
+--------------------+ +-----------------------+ +---------------+ +-------+
| apache1.3(mod_perl)| | apache1.3(mod_php/cgi)| | apache2.0(SVN)| | tracd |
+--------------------+ +-----------------------+ +---------------+ +-------+

#あとも一個別に開発環境

さらに物理メモリ使用量が減り3Mくらいになりました。
フロントのプロセス上げ放題です。

フロントがmod_perlとかmod_phpに依存しなくなっちゃったのでapache2.2.3を入れる事にしました。preforkです。
これで今っぽい構成になってきました。


+----------------------------+
| apache2.2(static/mod_proxy)|
+----------------------------+
|
+----------------------------------------------------------------+
| | | |
+--------------------+ +-----------------------+ +---------------+ +-------+
| apache1.3(mod_perl)| | apache1.3(mod_php/cgi)| | apache2.0(SVN)| | tracd |
+--------------------+ +-----------------------+ +---------------+ +-------+

#あとも一個別に開発環境

phpとかcgiは
RewriteRule ^(.*\.(cgi|php3?))$ http://example.com:81$1 [P]
みたいな感じでforwardしてます。
ハマりどころはnph-なやつまでproxyすると、リクエストが全部処理されるまでクライアントが表示されなくなるので
RewriteRule ^/nph-ss(.*)$ /nph-ss$1 [PT]
みたいなことしてます。

とりあえず、こんな感じで再構築してちょっとは軽くなった気がしてます。
今後は画像のクライアントキャッシュとか設定をつめてみようかなぁと思います。
圧縮系はやらないです、トラフィックより負荷対策優先で。
mod_phpまでやったのは、折角だからとことんフロントのメモリ使用量さげちゃおうって事と、あんまりphpの為にプロセス上げとくのも無駄だからなぁって感じからでした。

そういえば

ProxyPassReverse / balancer://
みたいな設定書いてるblogを良く見かけますが、それ動かないよ。
ProxyPassReverseってbalancerを展開してくれないよ。
そのかわり複数書けるから
ProxyPassReverse / http://ap1
ProxyPassReverse / http://ap2
ProxyPassReverse / http://ap3
な感じで書こうね。

Posted by Yappo at 20:56 | Comments (1) | TrackBack

2006年06月15日

Control Google Maps via MacBook

Control Google Maps via ThinkPad

Another day, another hack. Here's a demo that controls Google Maps using ThinkPad Hard Drive Active Protection sensor. Pretty cool.

というわけで ThinkPad ハックづいてるこの頃(といっても2日ですが)、また面白いハックを1つ。Google Maps の地図を、ThinkPad を傾けてナビゲートします。まずはデモをどうぞ。

というわけでMacハックづいてた自分も負けてられないと同じような物をMacBookで。

The code is available here in my archive site

AMSTrackerと、このスクリプトを同じディレクトリに入れて起動するだけです。
傾きを検知したらAppleScriptからSafariにJavaScriptを投げつけています。MacOSだからできるワザ。

まだまだ夢がひろがりんぐ。

Posted by Yappo at 04:27 | Comments (1) | TrackBack

2006年06月08日

tracとsvnwebとapache1.3.*でオープンソース開発環境の構築

http://plagger.org/のようなtrac&svn環境を作りたかったので頑張ってみました。
Apache1.3系でtracとsvnwebの構築をしました。
例としてBloxabというプロジェクトを立ち上げる時の構築方法で書いていきます。
ディレクトリとかユーザー名とかは適時書き換える事。
tracの細かい事についてはドキュメントとかを参考に。

svnリポジトリの作成


$ svnadmin create /usr/local/bloxab/repos
普通にリポジトリを作ります。
この作成したリポジトリは、apacheとtracdを動かすuid双方で読み書きできるしておく必要があります。
適切なchownとchmodをしておいて下さい。
以上

tracのインストール


tracを動かす為の各種ソフトをインストールします。
インストール方法は付属のドキュメントなどを参考に。
http://www.sqlite.org/からsqlite3をダウンロードしてインストール
/sbin/ldconfigを実行しておく
http://initd.org/tracker/pysqliteからPySQLiteをダウンロードしてインストール
http://www.clearsilver.net/からClearsilverをダウンロードしてインストール
http://www.edgewall.com/trac/からtracをダウンロードしてインストール

svnweb環境のインストール


mod_davを動くようにしてapache2を入れて、Subversion付属のmod_dav_svnとmod_authz_svnをいれてください。
なぜかapache2.2.2ではうまく動いてくれなかったです。

tracの設定


tracのプロジェクトを作成します
trac-admin /usr/local/bloxab/trac initenv
repositoryは/usr/local/bloxab/reposを指定します。
tracでの権限設定は
$ sqlite3 /usr/local/bloxab/db/trac.db
sqlite> delete from permission where username = 'anonymous' and action not like '%VIEW';
として匿名アクセスは読み込みのみ許可に変えてます。
管理者権限設定は
$ trac-admin /usr/local/bloxab/trac permission add MyName TRAC_ADMIN
してます。

認証ファイルの用意


svnのcommitとtracで使用するパスワードファイルを作成します。
$ htpasswd -c /usr/local/bloxab/trac/htpasswd MyName

tracdの起動


tracdはたまに落ちるという話をmiyagawaさんから聞いたので、mysqlを参考にtracd_safeという落ちてもあげ直すスクリプトを書いたので、これを使って起動します。
$ tracd_safe&
これでport 11001 でtracdがあがりました。

svnwebの設定


先ほどインストールしたapache2のhttpd.confを下記のようにします
LoadModule dav_svn_module     modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so

Listen 127.0.0.1:11002
ServerName svn.example.jp:80

<Location /repos/bloxab>
DAV svn
SVNPath /usr/local/bloxab/repos

# how to authenticate a user
AuthType Basic
AuthName "Bloxab repository"
AuthUserFile /usr/local/bloxab/trac/htpasswd

# For any operations other than these, require an authenticated user.
<LimitExcept GET PROPFIND OPTIONS REPORT>
Require valid-user
</LimitExcept>
</Location>

これでapache2を起動すれば
$ svn co http://localhost:11002/repos/blocab
でチェックアウト可能です。

apache 1.3系用のモジュールを追加


まずmod_proxyを入れておきます。
そして、そのままだとmod_proxyでsvnwebへのリクエストを通せないので、apache1.3系用のmod_davを入れます。
http://www.webdav.org/mod_dav/です。

フロントエンドのapache設定


今まで立ち上げたtracdとsvnwebをまとめます。
普段お使いのhttpd.confに下記の行を追加(もちろんdns周りは設定する事)
#for tracd
<VirtualHost example.jp>
DocumentRoot 適当に
ServerName example.jp

RedirectMatch ^/$ http://example.jp/trac
ProxyPass /trac http://localhost:11001/trac
ProxyPassReverse /trac http://localhost:11001/trac
</VirtualHost>

#for svnweb
<VirtualHost svn.example.jp>
ServerName svn.example.jp
ProxyPass / http://localhost:11002/
ProxyPassReverse / http://localhost:11002/
</VirtualHost>

logとかその他は適当に設定して下さい。


だいたいこんな感じでplagger.orgのような環境が出来上がります。
これでhttp://example.jp/にアクセスするとtracにhttp://svn.example.jp/repos/bloxab/にアクセス/svn coする事が可能になりました。

Posted by Yappo at 13:53 | Comments (0) | TrackBack

2006年05月26日

【デモ動画】MacBookの仮想ディスクトップをモーションコントロールで切り替え

VirtueDesktopsとParallelsを入れてわーい^^わーい^^してたら。
SmackBook Proというのを発見した。
でもこれは、他の仮想ディスクトップソフト使ってるし、パッチ当てなきゃいけないのでめんどくさいし、叩いてると壊れそう(^^;
なので考えたあげくPerlとAppleScriptを組み合わせてVirtueDesktopsでも動くようにしてみた。

goto YouTube
センサーの値が結構狭めなので右に移動しようとしたら左に行ったりとかで、ちょっとコツがいります。

多分、これを応用してMacBook本体をマウス代わりにして絵を描くとかできそう。
需要がありそうだったら、コードを整形して公開します。
多分geekでもhackerでも無い人でも普通に使えると思う。

Posted by Yappo at 03:06 | Comments (9) | TrackBack

2006年02月07日

suggest_ajax.jsのver0.2をリリースしました

id:onozatyさん作のsuggest.jsの拡張スクリプトsuggest_ajax.jsですが。

Enjoy×Study - suggest.jsのver0.2をリリースしました

yappoさんの「suggest_ajax.js - suggest.jsをAjaxなどに対応する等の拡張スクリプト」については、今回、関数名を一部変えた(keyup→keyevent)ので、ver0.2との組み合わせでは動かなくなります(せっかく取り上げていただいたばっかりなのに、、申し訳ござません…)。
という事なので、さくっと対応させました。

ソース
サンプル

主な変更点


  • suggest.js Ver0.2に対応

  • 候補リスト表示中のleft/right/return/esc key以外の挙動を変更

  • 候補リストを非表示中でも入力窓中でreturnを押すとblurイベントを発生させる

  • suggest.js Ver0.2で追加された要素には手を出していません。

    Posted by Yappo at 10:57 | Comments (0) | TrackBack

    2006年02月03日

    suggest_ajax.js - suggest.jsをAjaxなどに対応する等の拡張スクリプト公開

    先月suggest.jsというGoogle Suggestっぽい物を簡単に作れるスクリプトが公開されました。
    ちょろちょろっと自分の使いやすいようにカスタマイズしていたのですが、それを公開してみます。

    最初はAjax化でもしようと思ってたですが、Ajax処理内蔵するのもいけてないので付けるのやめました。
    ソースの中身は、全部なごりなのです。。。

    suggest.jsの思想の真逆を行っているなんて事は気のせいです。

    ソース


    suggest_ajax.js

    サンプル


    ajaxで補完リストを読み込む

    主な変更点


  • 補完リスト上でEnterキーを押して、選択肢の確定を行うことができる

  • 補完リストの作成直前と、選択肢の確定後のそれぞれにフックを行うことができるregister_hook()メソッド追加

  • 補完データを更新するreload()メソッド追加

  • 確定した入力内容を取り出すgetText()メソッド追加

  • 入力エリアの監視を停止するexit()メソッド追加
  • 使い方


    基本はsuggest.jsと同じです。
    <script src="suggest.js"></script>
    <script src="suggest_ajax.js"></script>
    ってな感じでロードしてください。
    呼び出し方は
                var suggest = new IncSearch.Suggest_Ajax(
    "text", // 入力のエレメントID
    "suggest", // 補完候補を表示するエリアのID
    list, // 補完候補の検索対象となる配列
    {dispMax: 10, interval: 1000}); // オプション
    と、同じ呼び出し方ができます。
    listはnew Array()と空の配列を入れることもできますし、オプションが無ければ
    var suggest = new IncSearch.Suggest_Ajax('text', 'suggest');
    と引数を省略できます。

    hookはserachblurに処理を挟む事ができます。
    searchでデータをAjaxかなにかで取ってきて補完リストを更新する処理を行います。

      suggestajax.register_hook('search', function (suggest) {
    var ajax = new Ajax.Request('./suggest_ajax.txt', {method: 'get', onComplete: function (res) {
    var list = eval(res.responseText);
    suggest.reload(list);
    suggest.search();
    }});
    });
    こんな感じで処理を入れます。
    reload()で一覧更新を行った後に必ずsearch()を呼び出してください。
    この呼び出しを行わないとsuggestが機能しません。
    この例ではsearch()をAjax.RequestのonCompleteの最後に入れることがコツです。

    blurについてはサンプルのソースを確認してください。
    exitは動作をとめるだけなので、特に説明しません。

    そのほか


    ライセンスはsuggest.jsと同じく「クリエイティブ・コモンズ 帰属 2.1 日本」
    十数行くらいsuggest.jsからコードをコピーしています。

    Posted by Yappo at 16:12 | Comments (2) | TrackBack

    2006年01月31日

    iアプリでUTF-8なHTTP通信をする方法

    ずいぶん古いネタですが、頼まれ事されたのでコード公開。

    iアプリの仕様としては、内部のエンコードがUCS-2という形式になっています。
    HTTP通信時にストリームをかますとSJIS←→UCS-2変換を行ってくれる仕組みがあるので
    iモードコンテンツと同じノリで、iアプリ向けのサーバプログラムがかけます。
    ただ、それ以外のエンコードの変換は行ってくれないのでサーバ側で吐き出すデータはSJISしか使えないのです。
    もしくはUCS-2を直接吐き出して、生ストリームで読み書きするとか。

    大昔にiアプリで動くBlogクライアントを書いたのですが、サーバ側のエンコードはUTF-8なのです。
    iアプリの機能ではUTF-8←→UCS-2なんて事はやってくれません。

    で、どうしたかと言うと。。。
    生ストリームでHTTP通信をして、ループでまわしてUTF-8←→UCS-2変換するコードで処理する。
    というありえない対処をしました。
    大昔のASCII本に掲載されているRSSリーダのソースには、もっとJavaっぽくUTF-8←→UCS-2なストリームを実装してました。
    というか、携帯でRSS!とか騒いでいる今日この頃ですが、大昔から実装はありましたよっと。

    で、自作のだめだめUTF-8←→UCS-2変換処理を晒します。

    UCS-2をUTF-8に変換しながらサーバに送信するコード

            int body_size = body.length();
    http = (HttpConnection)Connector.open(url,Connector.READ_WRITE, true);

    OutputStream dout = http.openOutputStream();
    for (int i = 0;i < body_size;i++) {
    int w_char = (int) body.charAt(i);
    if (w_char < 256) {
    dout.write((char) w_char);
    } else {
    int tmp;
    tmp = ((w_char & (240 << 8)) >> 12) + 224;
    dout.write((char) tmp);
    tmp = ((w_char & (63 << 6)) >> 6) + 128;
    dout.write((char) tmp);
    tmp = (w_char & 63) + 128;
    dout.write((char) tmp);
    }
    }
    dout.flush();
    dout.close();

    UTF-8をUCS-2に変換しながらサーバのデータを受信するコード
          in = http.openInputStream();
    din = new DataInputStream(in);
    int w_char;
    msg = new String();
    while ((w_char = din.read()) != -1) {
    if (w_char > 224) {
    int w_1, w_2, w_3, w_4;
    w_1 = ((w_char - 224) << 4);
    w_char = din.read();
    w_2 = ((w_char - 128) >> 2);
    w_3 = ((w_char - 128) << 6);
    w_char = din.read();
    w_4 = (w_char - 128);
    msg += (char) (((w_1 + w_2) * 256) + w_3 + w_4);
    } else {
    msg += (char) w_char;
    }
    }
    後は略

    といった感じで適当にビットシフトさせてます。
    まともにJava書いたこと無いので駄目駄目ソースですが、何かにインスパイアしてもらえたら嬉しいです。

    ちなみにライセンスは、この部ログにコメントすることでう。

    Posted by Yappo at 13:48 | Comments (1) | TrackBack

    2005年12月31日

    大晦日だからXangoをhackる

    ライブドアネ連発で年が終わるのもいやな感じなんですよ。
    ってか、ライブドアじゃなくて企業ネタで終わるのがね。


    というわけでXangoハック委員会です。
    だりいからターボールの提供のみで我慢してくらさい。

    ダウンロード

    なんせ年賀状コンテンツを作らんといけない。

    しばらく前に作ったXango製ロボットを公開するよ。
    robots.txtとmetaタグに対応してるはず。
    MySQLで管理してるよ。

    Xango最新版のみでしか動かないからSVNでとってきてね。
    しばらく稼動してると固まるバグもあるよ。


    配布ファイルのinit_db.sqlでテーブルを作ってよ。
    あとは、の

    __PACKAGE__->set_db('Main', 'DBI:mysql:MyRobots', 'user', 'pass');

    の所の場所を適度に変更しろよ。

    正直コードは適当だからな。

    じゃぁ、俺は高尾山で初日の出を見てくる。
    シュッ。

    全国のHackerよ!来年も鍛えような!シュッ!

    残念~Xangoも西村ひろゆきさんの会社ですから~
    2ch.net洗脳切り!

    って人も今年の年末はみないなぁ。

    Posted by Yappo at 23:24 | Comments (1) | TrackBack

    2005年12月16日

    W-ZERO3買った

    自宅に届いてたようなので使ってみました。
    IEはGoogle MapsとかAjax周りは扱えてなさそうだけど、Operaはちゃんと使えてたみたい。
    css周りが変で写真みたいな事になっちゃうけど、ドラッグとかも出来た。
    2005121601.jpg

    ターミナル環境としてはPocketPuTTYがあるようなので0.1を入れてみたが、マルチバイトが考慮されてないっぽ。
    SJISなサーバだったら日本語使えそうだけどね。。。
    あとCtl-Cとかがちゃんと送れてなくてmewツカエナサス。
    キーバインドの変え方調べないと。。。
    緊急時には何とか作業できるレベルかな。。。
    何でもいいから日本語ターミナルが欲しい所。


    とか言ってる間に電源切れないほど固まった。
    どうみてもWindows端末です。
    本当にありがとうございました。

    Posted by Yappo at 18:07 | Comments (0) | TrackBack

    2005年12月06日

    Apache 2.2.0 mod_proxy_balancer hacks of failure.

    mod_proxy_balancerを拡張して動的にごにょごにょしてやろうと思ったのに出来なかったからコアダンプ

    基本的にLinuxとかの環境ではpreforkしてApacheが動いているはずですが
    mod_proxy_balancerの実装がちぐはぐだった。
    主なデータとして、balancer://スキームを取り扱っているproxy_balancerと
    各クラスタの面倒を見ているproxy_workerってのがあるのさ。

    で、バランサ管理画面でApacheの起動中に動的に設定変更出来る機能があるんだけど
    proxy_balancerで管理しているstickysessionとか、リクエスト回数/転送サイズでバランシングアルゴリズムを切り替えるフラグを管理してるのね。

    httpd.confを読み込むフェーズ中ならまだ良いんだけど、一度サーバが回り始めるとプロセス空間が別々になるのよ。
    で、preforkで動いてるのよ。
    メモリ空間がバラバラになってるのにproxy_balancerの中身弄ってるのよ。
    しかも、ご丁寧にapr_pstrdupまでしちゃって…
    変更したこと、他のプロセスから見えないのにね。

    でも、proxy_worker系のパラメタは平気。
    各ノードの重みとか、stickeysessionの値対応付けとか、クラスタの一時停止フラグとかの結構重要そうなやつ。
    何でかって言うと、proxy_worker構造体の中にsっていうメンバがいるんだけど、そのsってのがproxy_worker系パラメータを管理画面から書き換えるときに弄ってるとこなの。
    で、このsってのはスコアボード(共有メモリ)の中にいるので別プロセスからでも変更内容が分かるわけ。

    balancer系のデータもスコアボードに入れればいいんだろうけど、今のcoreの実装上、改造するのがキツイ、書き換え範囲多すぎ。
    そもそも、balancerとworkerの紐付けどうすr?worker新規作成したらどうすりゃいい?
    worker用のメモリも前もって確保しなきゃだめじゃね?
    てか、pre allocしてたら大規模運用じゃ意味ねえyp!pre allocした数以上の追加があったらどうすんの?
    とかとか

    struct proxy_balancer {
    apr_array_header_t *workers; /* array of proxy_workers */
    const char *name; /* name of the load balancer */
    const char *sticky; /* sticky session identifier */
    int sticky_force; /* Disable failover for sticky sessions */
    apr_interval_time_t timeout; /* Timeout for waiting on free connection */
    int max_attempts; /* Number of attempts before failing */
    char max_attempts_set;
    proxy_balancer_method *lbmethod;

    /* XXX: Perhaps we will need the proc mutex too.
    * Altrough we are only using arithmetic operations
    * it may lead to a incorrect calculations.
    * For now use only the thread mutex.
    */
    #if APR_HAS_THREADS
    apr_thread_mutex_t *mutex; /* Thread lock for updating lb params */
    #endif
    void *context; /* general purpose storage */
    };

    のmutexが気になるけど・・・
    mod_proxy系全般でmutex使ってなさげだし

    サーバ追加するだけで、自動的にクラスタ入りできるソリューションがApache 2.2単体で出来たらいいなぁと思ってたけど、もろもろあって実現きついぽ。
    追加されたサーバの検知デーモン中にhttpd.confを書き換えてrestartさせる感じかなぁ。
    てかmod_perlすりゃいいのか。いやプロセスでか過ぎだろw
    preforkやめてworkerにして

    ServerLimit 1
    StartServers 1
    MaxClients 150
    MinSpareThreads 25
    MaxSpareThreads 75
    ThreadsPerChild 25
    とかにして、無理やり改造?

    mod_proxy系のTODOも見当たらないしワケワカンネ。
    なんとなくアーキテクチャの見直しが入る予感。。。

    どうすりゃいいんでしょうね。


    そうそう

    /* The number of dynamic workers that can be added when reconfiguring.
    * If this limit is reached you must stop and restart the server.
    */
    #define PROXY_DYNAMIC_BALANCER_LIMIT 16
    こんなのもあるんですよね。httpd.confの設定数+16個分のメモリ確保は出来てる。

    Posted by Yappo at 05:26 | Comments (0) | TrackBack

    2005年12月02日

    Apache 2.2.0 のロードバランス機能(mod_proxy_balancer)を使いこなす

    Apache 2.2がでました。
    mod_dbdとか、mod_proxy_balancerとか気になる新機能てんこ盛りです。
    ひげぽんさんの所に

    誰か入れてみた人いますか?

    と有ったのでmod_proxy_balancerを試してみました。

    超簡単でした
    mod_proxymod_proxy_balancerを参考にしました。
    既に日本語ドキュメント完備!

    以下から駆け足で、またセキュリティ的によろしくない設定例が多々あります

    とりあえずこんな設定を仕込んでみました

    ProxyPass /lb balancer://TEST stickysession=sesid
    <Proxy balancer://TEST>
    #1
    BalancerMember http://i.yappo.jp loadfactor=10
    #2
    BalancerMember http://www.google.co.jp loadfactor=5 route=2
    #3
    BalancerMember http://www.yahoo.co.jp loadfactor=5 route=3 redirect=2
    #4
    BalancerMember http://127.0.0.1:8081 loadfactor=1
    #5
    BalancerMember http://127.0.0.1:8082 loadfactor=1 route=4 redirect=2
    </Proxy>
    基本的には、リバースプロクシを仕込むのと大差ありません。
    balancer://hogehogeは、複数扱うことも可能です。
    バランシング方法は、転送サイズとリクエスト数のどちらかが選べますが、分かりやすくするためにリクエスト数にしておきました。
    loadfactorというパラメータは、優先順位みたいなもので、今回の設定だと1 1 2 3 1 1 2 3 1 1 2 3 1 1 2 3 4 1 1 2 3 5という感じでバランシングされました。
    細かいパラメータはProxyPass ディレクティブを参考してください。

    mod_proxy_balancerで嬉しい機能は、バックエンドのWebサーバが停止した事を自動的に検知して、止まってるサーバにリクエストを投げないですむ事です。
    また、専用の管理画面も提供しているので、どのクラスタのどのサーバが落ちてるかが一目瞭然です。

    <Location /LBMAN>
    SetHandler balancer-manager
    </Location>
    という設定を仕込むと
    http://localhost/LBMAN 経由から管理画面にアクセスできます。
    また、管理画面にてhttpd.confで設定した内容を動的に変更することも可能です。
    また、指定したバックエンドサーバを利用しないようにする設定も簡単です。
    後ろのサーバ一台だけメンテしたい!って時にも最適です。


    極めつけはstickysessionです。
    これは、CookieもしくはURLの文字列の中に指定したパラメータ名があると、そのパラメータを見てどのサーバを振り向けるかを明示的に指定可能になります。
    今回の例だとsesidというパラメータ名です。
    route=3っていう設定に意味があります。

    具体的にはApacheが

    GET /lb/ HTTP/1.0
    Cookie: sesid=hogegege.3;
    というリクエストを受け取ったらYahooに強制的に振り向けます。
    で、redirect=2についてですが、stickysessionに適合したサーバが落ちていた/管理画面で利用停止した場合に代替的に振り向けるサーバになります。
    Yahooが落ちていたらGoogleに振り向けられるわけです。
    で、代わりのサーバも利用不可能だったらランダムにバランシングされます。

    で、携帯電話とかはCookieが使えないものが有るのでどうしようって、感じですがバッチリ対応しています。
    こんなリクエストがくればおkです。
    GET /lb/?sesid=iofhwehg.3 HTTP/1.0
    POST /lb/?sesid=iofhwehg.3 HTTP/1.0
    GET /lb/hogege/sesid=iofhwehg.3 HTTP/1.0
    GET /lb/hogege/sesid=iofhwehg.3?id=hogaga HTTP/1.0
    GET /lb/dyfoeifYGfiussesid=iofhwehg.3 HTTP/1.0

    ただし、下記の例は動きません。
    GET /lb/?sesid=iofhwehg.3&id=hoge HTTP/1.0
    GET /lb/?sesid=3 HTTP/1.0
    GET /lb/sesid=sddas.3/hoge HTTP/1.0

    これには理由があって、以下の条件を満たすURL文字列でないといけないのです。
    1.stickysessionに指定された文字列がある
    2.stickysessionに指定された文字列の直後が=である
    3.そのパラメータの値には.が入っている必要がある
    4..以降から、URLの末尾もしくは?が出てくるまでの文字列がrouteで設定されてなければならない。

    こんな感じです。
    だからPOSTでも何でも条件さえ満たしてれば携帯でも使えます。
    要はURLの末尾に必ずおけばいいです。

    なんてのは大嘘で、おそらくバグがあって上の例じゃどうやっても動きません。
    GET /lb/?sesid==iofhwehg.3 HTTP/1.0
    のように=を2個つなげればいけると思います。(Cookie使うのだったら問題ない)
    たぶん、なんらかの間違いだと思いPatchを付けたバグレポート出してみました


    Webアプリ側ではstickysessionに配慮した構築を行わないとstickysessionを使いこなせなさそうですが、stickysession使わなければとてもお手軽にバランシング出来るので、あとは安定稼動すればおkなだけ!


    オマケ:管理画面にxmlというパラメータを渡すと…(例: http://localhost/LBMAN?xml=1 )設定がxmlで取り出せます。多分作成中の画面かと。

    Posted by Yappo at 21:48 | Comments (1) | TrackBack

    2005年10月14日

    J-PHONEでのIMGタグとMultiViewsについてのはまりどころ

    j-phoneの端末でimgタグのsrc属性にアクセスを行うときはAcceptヘッダを明示的に指定しています。

    Accept: image/jpeg, image/png

    って感じで、端末が表示可能な画像形式を羅列します。
    これがApacheのMultiViewsとの相性が悪くなるケースがあるというお話。
    1.3系です。

    たとえば/img.phpという画像吐き出しスクリプトがあったとして

    <img src="/img?img=hoge.jpg">

    っていうタグがあったとします。
    その場合には406エラーが発生して画像が出てこなくなります。
    406というのは、リクエストされたURIはクライアントが要求したAcceptとマッチしてませんよ
    みたいな感じのエラーです。

    原因がわからずapacheのソースを軽く調べてみました。

    この時携帯は

    GET /img?img=hoge.jpg HTTP/1.0
    Accept: image/jpeg, image/png
    以下略

    みたいなヘッダを吐きます。
    サーバ上に/imgってファイルが無いくてMultiViewsが設定されている時は
    mod_negotiationのhandle_multiに処理が引き渡されてdo_negotiationに変移して
    406エラーを返しているようです。

    結局、/imgから/img.phpというファイルを探し出して.phpのmime typeを調べた結果
    端末が要求しているAcceptのmimeとサーバで指定されている.phpのmimeが一致しないので
    406エラーを返すという挙動っぽいです。

    .phpのmime関連付けを image/jpegにしたところ406エラーは出ませんでした(代わりにphpのソースコードがダウンロードされるけど)
    .phpのmime関連をなくしたら404が帰ってきました。

    Apacheのマニュアルによると

    MultiViews 探索は、Multiviews オプションにより有効になります。サーバが /some/dir/foo へのリクエストを受け取り、/some/dir/foo が存在しない場合、サーバはディレクトリを読んで、 foo.* にあてはまる全てのファイルを探し、 事実上それらのファイルをマップするタイプマップを作ります。 そのとき、メディアタイプとコンテントエンコーディングは、 そのファイル名を直接指定したときと同じものが割り当てられます。 それからクライアントの要求に一番合うものを選び、 そのドキュメントを返します。

    とありますが、正確にはmime定義されている拡張子しか保管してくれないってこと?

    いや、ソース読めば判ることですが、そこまでは【許してください。】

    Posted by Yappo at 15:50 | Comments (1) | TrackBack

    2005年09月27日

    中国・韓国からのメールを拒否します

    中国(.cn)と韓国(.kr)に割り当てられたip addressからのSMTP要求を全てブロックすることにしました。
    最近ますます無節操なinfo@系のspamerの接続元がこの地域の割合が多い感じだったので
    というのと
    この地域からの人からメール来たこと無いので
    この地域からのSMTP要求を受け付けている事の実害の方が大きくなりすぎているため弾く事にしました。
    TCP全部弾くのは被害でかすぎな気がするのでやめます(中国iモードから見れなくなる)
    MFPM周りで、海外の人のコンタクトも出てきてるのでちょっと怖いですが。

    やり方
    韓国 IP アドレスからのパケットを遮断するから、ご希望の地域のip address listを取得
    リストに下記のスクリプトを通してsmtpのみ弾くように加工


    while(<>){
    s/ -j / -p tcp --dport 25 -j /;
    print;
    }

    あとは、先ほどのサイトの説明どおりに設定を仕込むだけ。

    追記:
    穴があったので、3つルールを追加


    iptables -A KRFILTER -s 58.18.0.0/16 -p tcp --dport 25 -j KRFILTERED
    iptables -A KRFILTER -s 58.180.0.0/16 -p tcp --dport 25 -j KRFILTERED
    iptables -A KRFILTER -s 203.67.0.0/16 -p tcp --dport 25 -j KRFILTERED

    適時増やす感じかな

    Posted by Yappo at 11:01 | Comments (0) | TrackBack

    2005年08月09日

    PowerEdge850がDellみたい

    デュアルコアなP4の搭載が可能で8G間でのDDR-2 SDRAMが乗るE7230チップだそうだ。
    価格は$749~だそうで、$2000くらいの構成を選ぶ感じになるかな。
    早速人柱になってみるか

    むしろ一台あたり10万以下の構成がたくさん欲しいわけだが。

    Posted by Yappo at 11:04 | Comments (0) | TrackBack

    2005年07月13日

    Google Maps APIでつながる世界

    Google Maps APIを使ったphotos@Yappo mapsに色々機能を付け足してみました。

    Nakamura-KU ADDICTさんのinvGeocoder WebServiceを使って、表示中のMapの中心座標に位置する住所表示を行ったり
    Yahoo!MAPSへのリンクをつけて、Google Mapsで対応していない日本地図を簡単に見れるようにしたり。
    Ajaxを使って、他人が表示している座標をリアルタイムで表示するLiveモードをつけたりしました。
    Google Mapsの座標が日本測地系になっていたので、Location::GeoToolを使ってサーバ側で座標変換を行ったりしています。

    Google Maps APIが出たおかげで、普通の人がなかなか活用できなかったGPSメールを簡単に貼り付けたり。
    GPS座標の住所変換も、簡単にGoogle Maps APIと繋げて活用できたり。
    はてなのようなサービスがキーワードなどで座標対応するようになって、その座標つきキーワードをRESTで簡単に取得して自分の所のGoogle Mapsと簡単に組み合わせられたり。
    地図サービスへのリンクを行う事で、楽に地図を探せるアプリケーションが簡単に作れたり。
    Liveモードのような物を作って、他人の興味のあるエリアを簡単に発見できたり。

    と、Google Maps API公開のおかげで、手を出しにくかった位置情報が簡単に扱えて
    今まで単体で機能していた位置情報サービスが、Google Mapsを中心に急速に繋がっていく様は面白い感じですね。

    これがWeb2.0の世界の入り口って所なんでしょうか。

    追記:
    一晩明けたら本家に地図搭載wwwwwwwwww
    おかげでネタ増えたですが、タイミングワルス

    Posted by Yappo at 20:36 | Comments (3) | TrackBack

    2005年07月11日

    はてなマップのデータを引っこ抜いて、自分のマップに貼り付ける

    google maps APIに乗っけるデータが、自分のところだけだとどうしても寂しいので
    はてなマップで使っているデータを表示するようにしてみました。
    浜松町周辺

    はてなマップはAjaxで座標系データを取得していて
    現在表示している座標内のデータのみを取得しています。
    せっかく外部サイトで利用しやすい形になっているから、つかってみちゃえとw

    専用のアイコン作って、はてなデータをわかりやすくしないとなぁ。。。

    Posted by Yappo at 10:46 | Comments (0) | TrackBack

    2005年07月09日

    Google Maps APIおもすれー

    日本のサービスでも組み込んでいる所が増えていて流行の兆しですが。
    ちょうど暖めていたサービスとの相性が良いので使ってみることにした。
    ドキュメント読むのがだるくてよく読んでないけど遊んでみた

    AUのGPS機能が返す座標の度数変換をしなければいけない事が分からずちょっとはまった。

    Posted by Yappo at 14:27 | Comments (0) | TrackBack

    2005年06月29日

    MySQLとSenna+MySQLのメモ

    ただのメモ

    SQL_CALC_FOUND_ROWSを使うと、結局最後までMYDを見ちゃうからパフォーマンスが落ちる
    match文を使いつつfieldに通常のwhereすると結局limitの数だけwhereの条件に一致するレコードを読んで遅くなる。要するにmatch文だけなら、それだけで読むべき行が求まるのにMySQLの通常の演算が入るとまんどい。
    alter table order byして、あらかじめソートしたテーブルも、MySQLのindexをキーにして検索するとselect order byしないと結果にならない。でもSenna+MySQLのfulltextインデックスのみでwhereしたら意図したとおりになる。
    少なくともSenna Rev21のバインディングではこんな感じ

    Posted by Yappo at 03:56 | Comments (0) | TrackBack

    2005年06月03日

    Linux Conference 2005 発表資料

    お話してきました。
    今日の敵は尿意でした。
    いやな汗ずっとかいてました。
    我慢してたら最後の方は収まってきました。

    あと、パワポのリハーサル時のページ切り替えタイミングを保存していたらしく。
    パワポとも戦いました。
    二面楚歌です。

    ということで、発表資料です。
    Yappoの思想すべて見せます
    題名の突っ込みは、本人からのみ受け付けます(え?)
    iYappo/YappoLabsでの実例やアーキテクチャ紹介を交えながら、選定基準や今後の事について話しました。
    正直いうと要求に見合った選定をきちんとする事が大事です。
    終わった後に、とある知人が経営している会社の中の人から、オススメを聞かれたですが機会があれば後日お話できればいいな。という感じです。

    ところどころ、笑われるようなネタを入れつつって感じです。
    途中、サーチストリームのデモを行いました。

    スタート
    スタービーチ(6) アルバイト(24) 任天堂(51) 淫らな告白(7) 着うた フル(151) 恋 画(2383) 翻訳(102) (?) 任天堂(51) 改造コード(14) 画像(1741) ??????(?) 怖い(64) 個人輸入(68)
    --------------------------------------------------------------------------------
    終了。

    狙いどおり、変な言葉が出たです。

    後半は、あんな検索会社検索会社検索会社なんていう凄いところへ言ってきて、お話した内容をサマリーにした感じです。
    検索会議でスルーされたネタの真意でもあります。


    というわけで、お呼びいただいきありがとうございます。

    突っ込み、個別質問なんでもござれ。

    Posted by Yappo at 16:40 | Comments (2) | TrackBack

    2005年05月31日

    既存のページにもんたメソッドを簡単に組み込むツールを作った

    いま巷を騒がせているもんたメソッドですが、あのプレゼンを再現しようとしたツールが2つ登場しています。
    もんたメソッドなプレゼン作成ツール
    もんたメソッドなプレゼンツール in XUL

    miyagawaメソッドとかカカクメソッドとか、○○メソッドという用法が普及しそうな感じですな。

    実は、自分も作ろうとしていた所なのですが、これらプレゼン風のツールとは違い
    簡単にWebサイトに貼り付けられる物を作りたかったのです。
    せっかくなのでサクッと作りました。

    以下もんたメソッド for Webサイトによる説明です(塗りつぶされてる所はクリックです)

    もんたメソッド for Webサイト とは?

    どんなページにも簡単にもんたメソッドを組み込む為の、小さいJavaScriptです。
    このページのように、重要そうな文字を隠しておくことが出来ます。

    貼り付けかたは
    http://tech.yappo.jp/download/monta.js.txt
    からJavaScriptを取得して、適当なURLにファイルを保存します。
    そして、保存したJavaScriptファイルを外部から呼び出すようにHTMLを編集します。
    onLoadに指定するのはちょっとやなので、htmlの後ろの方に<javascript src=" なタグを組み込みます。

    たとえば、このページは


    <script type="text/javascript"><!--
    var monta_close_font = '#00f';
    var monta_close_back = '#00f';
    var monta_open_font = '#f00';
    //--></script>
    <script type="text/javascript" src="http://tech.yappo.jp/download/monta.js"></script>

    で、実際に隠したい文字列を<span monta="on"></span>で囲みます。
    spanタグにmonta属性を勝手に追加した形になります。
    また、いくつかの変数に値を入れて置く事により、色などの変更が出来ます。

    monta_close_font - 文字を隠すときの文字色
    monta_close_back - 文字を隠すときの背景色
    monta_open_font - 文字を表示したときの文字色
    monta_open_back - 文字を表示したときの背景色
    monta_close_img - 文字を隠したときの背景画像


    var monta_close_img = 'url(http://example.com/back.jpg)';

    のように利用する。
    (でもMTで使うとうまく色がつかないorz)

    適当な実装ですが、違和感無くもんたメソッドを組み込めるかと思います。

    Posted by Yappo at 23:23 | Comments (4) | TrackBack

    2005年05月28日

    Blog Hackers Conference 2005 発表資料

    お話してきました。
    唯一笑いが出ないセッションという貴重な体験です。
    何でかというと、初スピーチで必死です。
    最後にnaoyaさんに激しく「必死ですから」と言い放ってしまうほど危なかったのです。
    余裕の無さをアピールしても見てる人にはどうでもいい事なので、淡々と進めたです。
    また機会があったら、も少し余裕出来るかな。
    オファー頂いたmiyagawaさんに感謝の念なのです。

    ということで、発表資料です。
    あなたのHackに検索を
    Hyper Estraier, Senna, Rastの紹介です。
    思ったままに書き綴っています。
    開発者の方々へのネゴ無しの発表なので、とても背中が痛いのです。
    でも、一人でも興味持ってくれる人が増えたら嬉しいなと言う1ユーザの主張として。

    11Pは独断と偏見に基づき評価しています。
    どのソリューションを選ぶかは、本人が決めるべきだと思うので、知らない人が勝手に作った評価程度だと思って見て下さい。

    ?が付いてる分には、未調査などにより評価不能という意味です。
    11P、12Pに関しては詳しい説明が必要だと思いますが、今日は勘弁してください。
    今日ゲッツ出来たお土産写真の準備をしなきゃいけなくて忙しいのです。


    にぽたんさんのおかげで、DBIx::QueryCacheのCPAN登録作業に俄然やる気でてきますた。

    追記:
    たつをの ChangeLog Blog Hackers Conference 2005より


    そういえば、SUFARY ももともと
    Cライブラリがメインなので組み込み用途と言えるかも!

    もちろん存じてるでっす!
    7年くらい前にいじろうとしてたんですが、別の事にはまってて遊ぶのわすr。。。
    とある老舗検索会社さんに採用している事を教えてもらってたです。

    Posted by Yappo at 03:01 | Comments (0) | TrackBack

    2005年05月27日

    今日はBlog Hackers Conference 2005ですよ

    いやはや、どんな事になるやら。

    と思ったら参加エントリー忘れてたorz

    Posted by Yappo at 15:52 | Comments (0) | TrackBack

    2005年05月23日

    ああぁぁあBlog Hackers Conference 2005でお話ししちゃうぅ(><)

    って事で、第一回チキチキBlog Hackers Conference 2005にて5分間話してきます。
    (第二回じゃないよ、2005って付くのは1回目だよ)
    壇上で喋る事なんか初めて、でもないやライブしてたや、じゃぁいいや。

    ネタは検索系で攻めようかと、え?Blog関係ないじゃん?
    まぁまぁまぁ

    今話題の検索周りを使った、Blogにまつわるネタ出しでも出来たらなぁと思いますです。
    実例のスクリプト書こうとも思ったけど高橋メソッドでソースを見せなきゃ
    後ろの人たちが分かりづらいので却下の方向で。

    はてなブックマークを、とある実例として紹介するかも。

    Posted by Yappo at 12:12 | Comments (0) | TrackBack

    2005年03月15日

    BIG-IP v9 memo

    @ITより。
    製品詳細

  • カーネルがLinuxに

  • TMMデーモン

  • フルプロクシアーキテクチャ
    L4以上のデータをいじれるそうで

  • UDP正式対応

  • OneConnect
    Apacheのモジュールに特殊な事やってたら問題ありそうね

  • HTTPリクエストのパイプライン化
    モバイルサイトで絶大な効果かな

  • gzip圧縮
    レスポンスデータを透過的に圧縮するそうで

  • IPv6/IPv4ゲートウェイ
  • BIG-IP側に全部任せちゃうと大変な事になりそうでもあるな。
    最上位モデルで32/64 bit HyperTransport 2.4 GHz x 2と専用ASIC搭載だそうだ。

    ハードはいいから、これらを実現するソフトをだれか作ってないかな

    Posted by Yappo at 16:56 | Comments (0) | TrackBack