ziguzagu.org

ADD cpanfile cpanfile.snapshot /app
RUN cd /app && carton install --deployment

などしてコンテナ内に CPAN モジュールを含めておく場合、ローカルリポジトリの cpanfile の mtime が変わるようなことが起きると ADD によるキャッシュはきかず carton やり直すはめになり時間がかかる。

CircleCI で Docker を利用してテストする際、ローカルリポジトリはキャッシュから展開されて clone ではなく pull されるようになっているので、cpanfile に実際の変更がなければ mtime 変わらないが、なぜか変わってしまうことがたまにあって時間がかかってしまうことがあるっぽい。

これは、ADD するファイルの mtime をコミット時の Commit Date に変更して、ファイルの内容に変化がなければ mtime も変わらないようにすることで防ぐことができる。

#!/usr/bin/env bash
set -eu

for file in $*; do
    touch -m -t $(date -d "$(git log -1 --pretty=format:%cd --date=iso $file)" +%Y%m%d%H%M.%S) $file
done

というスクリプトをリポジトリ内に用意しておいて、

checkout:
  post:
    - tools/git-mtime cpanfile cpanfile.snapshot

と docker build する前に ADD するファイルは全部 mtime 変更やっておくとよい。

CircleCI に限った話でもないのでこのスクリプトは PATH のとおってる場所においておくと、

git mtime <file...>

として普段使いもできる(あまり使う機会はない…)。

そういえばずっと Gem 化しないまま使っていた capistrano-scm-tar を rubygems.org にアップロードしていたのだった(気づいたら年が変わっている…)。

名前の通り Capistrano 3 の scm として振る舞いつつも実際はなんもしなくて、ただ tarball をデプロイするためのプラグイン。

設定は deploy.rb などで scm を指定するのみ。

set :scm, :tar

デプロイは Capistrano 実行環境にファイルをアップロードするなりして、package 環境変数にそのパスを与える。

$ cap deploy package=/tmp/v1.0.0.tar.gz

結局 tar。

Mojolicious で X-Forwarded-For からプロキシではなくクライアントの IP っぽいものをとってこれるプラグインを書いた。

使い方は SYNOPSIS の通り、

use Mojolicious::Lite;

plugin 'ClientIP';

get '/' => sub {
    my $c = shift;
    $c->render(text => $c->client_ip);
};

Mojolicious 的にはリモートアドレス取るとなったら $c->tx->remote_address を使うのが通常だと思われるけど、これは XFF があったら最後の IP を単に返すだけ。一方このプラグインではプライベートネットワークなアドレスは無視するようになっているので、

X-Forwarded-For: 192.0.2.100 10.0.0.2 10.0.0.1

みたいの受け取った時に、

$c->tx->remote_address;  # => '10.0.0.1'
$c->clien_ip;            # => '192.0.2.100'

こういう違いが出る。XFF がなかったり、全てプライベートアドレスだったりした場合は $c->tx->remote_address が呼ばれるので、環境やミドルウェア的なものにあんまり左右されずに『ユーザーの IP』っぽいものをとりたい時に普段使いできるはず。

通常これだけで事足りるはずだけど、事情があって無視したい グローバル IP があったりもしたので、任意の IP を追加で無視できるようにもなってる。これも SYNOPSIS の通り、

plugin 'ClientIP', ignore => [qw(192.0.2.1 192.0.2.16/28)];

CIDR 使えるので楽。

さすがに手段も目的も当たり前すぎるものなのでもうプラグインあるだろと思ったけどみあたらなかったので作った。

最後かもしれない YAPC::Asia Tokyo 行ってきた。

久しぶりに2日間参加できてとても有意義だった。 といっても 2006 年の初回から計 9 回行っても素人の域を脱することができないためずっとトークを聞いていた(その割にベストトーク上位3つをどれも聞いていないかった…)。

印象深かったのは以下。

Effective ES6

残念ながらいわゆる片手間でフロントエンドもやっている身としては大変ためになった。 今メインで開発しているサービスでも使い始めたのでいい加減覚える。

TBD

Ruby の反省点として Lisp に(悪)影響を受けた部分のくだりの、 「ユーザーに微妙な使い分けを強いるような似たようで異なるもの導入すべきではない」というの、Web サービスの API 設計に通じるものがありそう。 API 作ってるときはその API を安定させるためにやることを 1 つにさせたいと思って作ることが多い。ただ、実際にはそのせいでクライアントは微妙に異なる複数の API を条件分けして使ったりで全体を通すと API 提供側でよしなにやったほうがテストもし易いのではという気がする。 次、そんな場面に出くわしたらちょっと考えてみよう。

Perl 5.22 and You

5.20 で導入されてた Post Dereferencing は見落としていたので知れてよかった。

ただ、5.24 についてもさらりと触れていたけど、今後並行処理サポートとか(Ruby で検討されてるらしい)Soft Typing みたいな新しい技術は入ってこないんだろうなという気がするのでなかなか寂しい状況。 Perl 5 と Perl 6 は違う言語であるということはさんざん言われてるけど、そうであれば Perl 6 が登場しようとしてる今 Perl 5 が単に死にゆく old version になるのか、別の言語として発展し続けるのか、その辺ちょっとメッセージがほしいかなぁと思った(自分がしらないだけでなんかすでにあるかしら?)。

Adventures in Refactoring

Developer Happiness、いい言葉だった。もろもろ共感する部分あり、身につまされる部分あり、なるほど感あり、とてもいいトークだった。 そいえばテストコードのリファクタリングはどうやって進めてるのか、きいてみればよかったと今更思った。 あとでもう一回スライド見直して脳内再生しよう

Parallelism, Concurrency, and Asynchrony in Perl 6

トークの聞きやすさ、わかりやすさもあいまってか、Perl 6 の並列、平行、非同期部分えらく良さそうに見えた。 言語のコア機能じゃなくてモジュールで実現されてるみたいなっぽいのでなんか変態的な気もするけど、Perl 6 ちょと期待してもいいのかなと思った。


YAPC::Asia は初回の思い出が強すぎるせいか、あの時のような YAPC をもっかい見てみたいという気もする(他力本願)。 一方で Perl の話メインでみっちりトークをするという役目は地域.pm に移ったかなという気はずっとしてたので、自宅の最寄りでもある Chiba.pm がまた開催されるようなら行ってみよう。

またトークばかり聞いてるだけかもしれないけど、そんなに遠くない未来にまた開催されるといいなぁ。

Data::ObjectDriver 0.10 をリリースした。

SIXAPART/Data-ObjectDriver-0.10

テストとドキュメントの修正だけのバージョンだけど 0.09 から 4 年弱を経ての復活。

大人の事情で宙ぶらりんになっていた PAUSE の SIXAPART アカウントを復活しつつ、前メンテナの Yann から Github 上のリポジトリを transfer してもらい再び Six Apart としてメンテナンスすることに。

sixapart/data-objectdriver

Pull Request もながらく放置されてしまっているけどなるだけ近いうちに対応する方向で。Movable Type をはじめその他のサービスでも使っているので、今後はそれなりにメンテナンスされていくことになるはず。

ご利用中の皆様におかれましては引き続きよろしくお願い致します。