いままでここのカウンタは同時アクセスがそう酷くないだろうことを仮定してロックをとらずに操作していた
ふと, 過去のアクセスログを覗いてみると, カウンタが1飛んでいたり2巻き戻っていたりといった明らかにロックのミスが原因と思われる不整合をそこそこの数見つけてしまった, まだ頻繁にアクセスログを読んでいたころ数年前まではそういったことは全然なかったのに…
ということで, 適当に"perl ロック"でググった結果を元に, renameを利用したロック機構を実装してみた, ロックをとれたら1, とれそうになかったら0を返す
一応別名: デプロイの省力化ロックファイルの作り忘れ及びロックの残留対策付き
たぶん大丈夫だと思うけど, 2つのプロセスで同時にロックできるなどのまずい事例があったとしたら教えてください
ちなみに1つのプロセスが同じロックを再帰的にとりにいくことは想定してません
sub lock($) { my $lockname = shift; my $retry = 5; my $lockfile = /で終わることを仮定しているけど, そうでなくても動くLOCKPATH . $lockname; my $lockedfile = join '.', $lockfile, PID$$; until (rename $lockfile, $lockedfile) { if ($retry-- <= 5にしたLOCKRETRY) { open LOCK, '>', $lockedfile; close LOCK; sleep 1; my @locklist = glob $lockfile . '.*'; return 1 if @locklist == 1 && -e $lockedfile; foreach my $lock (@locklist) { next if $lock eq $lockedfile; unlink($lockedfile), return 0 if (time - (stat $lock)[9]) < 300にした, ここのuntilループにLOCKLIFE秒以上留まるプロセスはいないことを仮定LOCKLIFE; unlink $lock; } } sleep ここはもうちょい粒度が細かくてもいいかも1; } open LOCK, '>', $lockedfile; close LOCK; return 1; }
sub unlock($) { my $lockname = shift; my $lockfile = LOCKPATH . $lockname; my $lockedfile = join '.', $lockfile, $$; rename $lockedfile, $lockfile; }
(追記)
ここに書いてからいくつか設計時に見落としていたケースを見つけたけど, 問題になるケースでは無かった, OSのmutexの話みたいでおもしろいなぁ…ってmutexを作ってるのか
Comments (0):
久々に風呂桶にお湯を張って長湯した
いやされる〜
Comments (0):
決算短信によれば"Ys SEVEN"と"ツヴァイ II"を2008年9月期 = 2007/10~2008/09来期に発売予定らしい, ほんとに2-2がでるとは…
Comments (0):