今までのページャは良くある ?page=2 みたいな形式でした。これは内部的には offset / limit を使う SQL になります。

変更したページャは /.page/20160509/3 という形式です。20160509 が表示するページ番号、3 がそのページに表示する最大の数です。ページ番号はトップページからのページの場合、日付になっており、内部的には日付ベースの where 句になります。3 は limit です。

これらによって、サーバ側のエントリ表示数のデフォルト設定によらず、URLによって決まる内容が生成されます。よって

  • キャッシュ無効化の負荷が減る
    • 古い形式だと ?page=xxx なキャッシュは1つエントリが増えるたびに全て無効にしないといけません
  • 古いページを表示したときの負荷が減る
    • offset / limit はそのページに至るまでの全てのエントリをソートして辿る必要があるので古いページをページ指定すると不穏な空気が流れます
  • 検索流入したとき見たいコンテンツがないことが防げる

余談:この日記の構造

このサイトは「日記」なので、日付単位でエントリがまとめられています。「ブログ」の表示に慣れていると違和感があるかもしれませんが、以下のような違いがあります。

  • ブログは全エントリを通して新しい順に並ぶ
  • 日記は日付単位で新しい順に並び、日付内では古い順に並ぶ

ちょうど、紙に日記を書くときのように、1日の中では連続し、1日単位では独立しているというイメージです。

この挙動は正直初見ではわかりにくいと思うのですが、過去分は1日単位で上から下へ書かれる前提で複数のエントリを構成しているケースがあって、変えるに変えれません。

  1. トップ
  2. tech
  3. ページャの実装変更

子供のおもちゃのチョロQを見ていて不思議に思ったことがあって調べたので書いておきます。

遊びかたの先入観

チョロQみたいなプルバック式のミニカーは、後退するときにぜんまいを巻き上げることで、前進時に動力にするわけです。なので、くるま全体を床に押し付けたまま前後してもぜんまいは巻き上がらず (後退で巻き上がっても前進させた分巻き戻る)、走らないと思っていました。

自分の遊んだ記憶だと、後退するときだけ押し付けて、一旦持ちあげてもう一度後退させていた覚えがあるのです。

いつこの「プルバックの走らせかた」を学んだのか全く覚えていませんが、当然そういうものという認識でいました。そしてそもそも「後退時に巻いたぜんまいで動く」以上の仕組みを知りませんでした。

実際の挙動

子供は「プルバックの走らせかた」を知らず、適当に前後させたらなんかうごくことだけ学習しています。

子供が遊んでるときの挙動を見てるいると、ただ床に押し付けてゴリゴリと前後するだけでもぜんまいが巻き上がり、しかもどう見ても巻いた以上に長い時間回転することに気付きました。

前進時と後退時でギア比が変わる。

Wikipedia の「プルバック式」の項を見ると

ゼンマイを使うプルバック式動力では、後退の時のみギア比の大きい状態になるよう、内部の歯車が浮き上がるようになっており、ゼンマイの力で前進する時だけタイヤを高速回転させるような構造を持つものも多い。

と書いてあって、ギア比が前進と後退で変わるような仕掛けがあるようでした。

「プルバック ギア」とかで検索すると、もうすこし詳しいページも見つかります。構成するギアのうち2つのギアの軸は方向によってずれることで、いずれか一方が噛み合うように調整されているようです。

もしかすると常識なのかもしれないですが、こういう面白い仕掛けがしてあるとは考えていなかったので、びっくりしました。

結局ガルパンは5回ぐらい見てしまった。劇場版がみたい。

ボトルガムを買うと、だいたい2日ぐらいでなくなってしまって金がもったいないという感じになってしまう。

職場にいると無限にストレスが溜まってるので、手の届くところにガムとか食べものを置いておくと無限に食べてしまう。もったいないので、できるだけ買わないで水をガブ飲みしてるけど、口が寂しい。

そういえば、ものすごくイライラしているときは掃除すると多少気が紛れる (やる気になった場合だけだけど)。すこし前にイライラしたときは、ひたすらトイレ掃除をしていた。

掃除には良い点がいくつかあって

  • 満足するまで終わりがない
  • 頭を使わない (普段使っている回路を使わない)
  • 目に見える成果がある

一定の「満足感」は手に入ることがほぼ保証される。そんなものは他にあるか? ネトゲとかは瞬間的な満足感はあるが社会的には虚しい。掃除は同居家族がいるなら社会的な利益もある。

しかし、どういった種類のことでも「やらされている」と思った時点ですべての利点は失われる。他人のために働くということをすると、自分で満足するということがなくなる。成果評価の裁量を他人に奪われた時点で生きてる実感はなくなる。

少しでもストレスが解消されることがら

  • 散歩
  • 掃除
  • 睡眠
  • うざくないお笑い番組 (内村さまぁ〜ずみたいなやつ)
  • 悪役が出てこないアニメ
  • 高徳な主人公のアニメ

大きくストレスが溜まることがら

  • 路上喫煙 (避けようがない)
  • 仕事 (避けようがない)
  • 自分から見て道徳感のない人間の存在 (避けようがない)
  • 道徳観のない人間の発言 (はてブを見なければ、ほとんどエンカウントしない)
  • 他人の儲かった話
  • 自分が直接的にしろ間接的にしろ否定されるようなナニか全般

他人の道徳観に関するストレス (路上喫煙も同じ) は「こんなやつが社会でうまく生きてるのに、なぜおれは社会でこんなに否定されているのか」という感情に基いている。

ps とかで表示されるプロセス名をわかりやすくしたいという話です。

Starman だと $0 に適当な値を入れてくれて、master なのか worker なのかとか、どの psgi が動いているかとかがわかるのですが、Starlet ではそういうことをやってくれないので、1つのサーバで複数インスタンス動かしていると、plackup のプロセスだらけで、どれがどれだかわからなくなります。

app.psgi で $0 で設定すれば良いかと思ったが

app.psgi で $0 設定したらとりあえずいいだろ、と思ってやってみましたが、どうも上手くいきません。app.psgi 内で $0 を warn してみるとそもそも plackup になってもいません。

調べてみると、Plack::Util::load_psgi で使っている _load_sandbox 内で local $0 をしてから app.psgi を do しており、ロード後に元のプロセス名に戻ってしまうようです。

ということで、単純に app.psgi で $0 を書きかえても plackup を使っている場合書きかわりません

Starlet 用のハックを入れる

なんかうまい方法がなさそうなので以下のようなクソハックを app.psgi に入れました。

{
    ### set process name for Starlet

    use Parallel::Prefork;
    my $name = $0; 
    my $orig_new = \&Parallel::Prefork::new;
    no warnings 'redefine';
    *Parallel::Prefork::new = sub {
        my ($class, $opts) = @_; 
        $opts->{before_fork} = sub {
            $0 = "$name (worker)"
        };  
        $opts->{after_fork} = sub {
            $0 = "$name (master)"
        };  
        $orig_new->($class, $opts);
    };  
};

Starlet は Parallel::Prefork を使っているので、前もって use して new を書きかえて before_fork / after_fork を設定します。

before_fork / after_fork は Parallel::Prefork の機能でセットできるフックポイントですfork 前に worker プロセス用の $0 を設定して、fork 後に $0 を master 用の値に変えています。なのでタイミングによっては master プロセスも一瞬 worker 表示になります。

app.psgi ロード時のコンテキストでは $0 には .psgi のファイル名が入っています。これは上記の Plack::Util::_load_sandbox で設定されたものです。ということで、ロード時のコンテキストの$0を保存しておいて、後の $0 の設定に使っています。

app.psgi が Starlet 専用みたいになってキモいですが、Parallel::Prefork をロードする以上の害はとりあえずないのと、自分の場合は開発中に Standalone で動かす以外は Starlet を使うことにしているので問題ありません。

これで以下のようになりました。

cho45     4699  0.0  0.5 185432  5332 ?        S    May11   0:00 /home/cho45/project/COQSO/script/app.psgi (master)
cho45     4700  0.0  2.4 296604 25168 ?        S    May11   0:09 /home/cho45/project/COQSO/script/app.psgi (worker)
cho45     4701  0.0  2.5 296820 26468 ?        S    May11   0:11 /home/cho45/project/COQSO/script/app.psgi (worker)
cho45     4702  0.0  1.8 302304 19136 ?        S    May11   0:11 /home/cho45/project/COQSO/script/app.psgi (worker)
  1. トップ
  2. tech
  3. Starlet でプロセス名をわかりやすくしたい

  • RTT (ping) が約30ms〜50msぐらいの環境
  • * がついているのは http2 の push
  • HTML 内で直接参照しているリソースについてもダウンロードしている (nghttp の --get-assets オプション)


岡元太郎の母の塔です。子供がこわいこわい言う。

  1. トップ
  2. photo


トラックバックを実装しました

といってもサイト内のエントリ間の言及を表示するだけです。いわゆる古代のオープンなトラックバックではありません。

古いエントリに新しいエントリへのリンクがないのは不便だなと思い、とりあえずさくっと LIKE 検索で機能を足してみていたのですが、良さそうなので、ちゃんとリレーションテーブルをこしらえたりしました。

しかし、全体的にページキャッシュ機能を入れているので、単に機能を足すだけでも考えることが増えてしまいます。イメージではトラックバックが送られたページに更新がかかるというだけですが…

キャッシュ処理も見直して、全体的にテストも書いたりしました。キャッシュが入ると複雑性が増す分、独り人力QAには限界があるので、みっちりテストを書くほうがかえって省力化します。

  1. トップ
  2. tech
  3. トラックバックを実装しました