Apr 19, 2013

(Image|Graphics)Magick は resize 後の横縦サイズは小数部分(第1位であろう)を四捨五入している。らしい。

Distort Resize - free-form resizing

All the above resize methods all have one limitation which we touched on earlier, they will round the size of the new image to an integer number of pixels, then map the old image's pixels to the new pixel array.

http://www.imagemagick.org/Usage/resize/

なので、サムネイル画像を動的につくっているけど、その img 要素の width, height を事前に埋めたいときには、四捨五入して計算すること。で、うまくいっている風。

この前、さくらの VPS が落ちて再起動されてしまったのち、いっしょに死んだままだった MT を久々に起動するにあたり carton 化しようとおもって作った cpanfile。

Starlet は適宜使いたいサーバーに、Server::Starter、XML::LibXML は不要であれば外しつつ、MySQL じゃないひとは DBD::mysql も適当に変更して、carton install すればできあがり。

% carton exec -- local/bin/start_server --port 8000 --pid-file=log/mt.pid -- plackup -s Starlet --max-workers=2 --access-log=log/access.log mt.psgi >& logs/error.log &

みたいな感じで起動。しかし、ログローテートもしてないしあんばいがよくないので supervisor で動かすようにする。いつか...。

Apr 05, 2013

CPAN Module の変更点をサクッと調べる方法

というエントリーに反応してみるテスト。

僕は CPAN Module のバージョン間の diff をとるのに、search.cpan.org にある diff 機能を使う以下のようなやっつけスクリプトを使ってる。

たまに空のレスポンスが返ってきたりするけど....、これを less とか grep -A100 .pm とかなんとかにパイプしたりしなかったりしてコマンドラインで生 diff を確認。Cache::Memcached::Fast の 0.19 と 0.20 だったら以下の様な塩梅。

パッケージまるごとの diff なので README とか、MANIFEST とかの差分もはいっててノイズがまぁまぁあるといえばあるけど、目 grep で除外...。

metacpan っていまだによくわかってないけど(汗)、同じようなのあるかしら。

Mar 14, 2013

この前つくった fluent-plugin-ganglia を gem にしてバージョン 0.0.1 をリリースした。

前回のエントリーで書いた時点では、gmond を multicast かつ upd_send_channel を bind_hostname = "yes" として動かしている場合に実はうまくいっていなかった。うごいた!とおもってあのエントリーをよろこびいさんで書いた時点では、1台のホストでしかどうささせていなくて、同じ metric group にはいる他のホストで動かし始めたら全然グラフでてこない、という始末...。

これは gmetric gem の Ganglia::GMetric#send が、

conn = UDPSocket.new
conn.connect(host, port)

conn.send gmetric[0], 0
conn.send gmetric[1], 0
conn.close

こうなってて bind してないからだったようで、Ganglia::GMetric#send は使わずにプラグイン内で、

conn = UDPSocket.new
conn.bind(HOSTADDR, 0) if @bind_hostname
conn.send gmetric[0], 0, @host, @port
conn.send gmetric[1], 0, @host, @port
conn.close

こんなような感じで IPSocket.getaddress(Socket.gethostname) でとってきた IP (HOSTADDR定数のところ) に bind して送るようにしたらうまく行った。まぁ、つまり bind_hostname = "yes" なんで bind しろよ、ということと思われる。gmetric コマンドを strace してみてても bind してたし(というか strace して差分みてて気づいた)。

この multicast + bind_hostname してる環境で metric 送りつけるには、こういう設定。

<match metrics>
  type          ganglia
  host          239.2.11.71
  port          8649
  group         metric_group
  name_keys     metrics.field1,metrics.field2
  bind_hostname true
</match>

bind_hostname true で bind してから送るようになる。multicast だけど bind_hostname してなければいらない。

というのを経ての 0.0.1 はコレの本番環境で絶賛稼働中。unicast での Ganglia はためしたことがないのだけどたぶんうごくとおもうので、もし試せる方おりましたらフィードバックいただけると幸い...。

ご利用ください。

Mar 06, 2013

Plack::Middleware::DefaultDocument というのを作った。

MogileFS のクライアントとしてだけ動く小さな PSGI アプリかいていて、MogileFS になかったらアプリがもってるデフォルトのファイルを 404 ではなく 200 で返したい、ということをやりたかったんだけど、これを実現する方法として、

  • app 側で対応する
    • 汎用的にしたかったのでなし
  • 手前にいる reverse proxy(apache2.2)にやらせる
    • プロキシした結果 404 だったら別の何かを 200 で返す、という方法がわからなかった
    • あったとしても mod_rewrite での対応となると今回はきつい
      • このアプリにプロキシされるまでにすでにカオス RewriteRule をくぐり抜けてきているので...
  • さらに手前にいる varnish / perlbal にやらせる
    • varnish がバックエンドから 404 うけとったら req.url 書き換えて restart、varnish の後ろにいる perlbal の web server につかませる
    • キャッシュがあればバックエンドひと通り巡るコストもなく速いが関係者が増えるのでなんかいや
  • Middleware::ErrorDocument で subrequest なげて Middleware::Static につかませる
    • 404 は普通につかいたいので、それとは別に enable_if { $_[0]->{PATH_INFO} =~ m{/favicon.ico} } ErrorDocument 〜 とかしてわけて、Static で path => sub { s/// } で PATH_INFO 書き換えて特定ディレクトリからさがす
    • 別にこれでよかった(え)

など堂々めぐりした結果、簡単にできるやつをということで作った。

使い方はこんなん感じ。

enable "DefaultDocument",
    '/favicon\.ico$' => '/path/to/htodcs/favicon.ico',
    '/robots\.txt'   => '/path/to/htdocs/robots.txt';

app からのレスポンスコードが 404 だった場合に、PATH_INFO が key の正規表現にマッチしたら value のファイルを返す、という動作をする。404 以外が返っていこうとした場合は何もしない。

MogileFS からファイル探して、なかったらデフォルトのなにかを必要に応じてだす感じだとこういう風の例。

DefaultDocument という名前は英語的、動作の説明的に微妙な気がしないでもない...。そして相変わらずの俺得 module 感...。