| @技術/プログラミング

以前、Unicorn が暴走して困ってるという記事を書いていた。しかしよくよく調べてみると暴走してるのは Unicorn ではなく、Syntax Highlight に使っている Python の Pygments を呼び出している Ruby のプロセスだった(pygments.rb)。こいつが CPU をバカ食いしてしまい、アプリケーションのレスポンスがすこぶる悪くなっていた。

少し前、Pure Ruby の Pygments 互換 Syntax Highlighter で Rouge というのを発見していたので、Python を spawn するプロセスがなくなれば CPU バカ食いも止まるはず、と思って pygments.rb から移行してみた。しかし…

なんと逆にサイトが重くなってしまった。やはり Pure Ruby のプログラムは重いみたいである。pygments.rb は C のネイティブコードも含んでいて、速さがボトルネックになるところは C で処理しているみたい。

というわけで残念ながら EC2 のマイクロインスタンスで Rouge を常用するのは無理そうなので Pygments + pygments.rb に戻します。あとはキャッシュして誤魔化すしかなさそう。

| @技術/プログラミング

一月くらい前から Lokka の master ブランチを自分のブログ用のブランチに merge してサイトをデプロイすると謎の白画面が出るようになっていて困っていた。現象は極めて謎で、ローカルの開発環境(RACK_ENV='development')では見られず、本番(RACK_ENV='production')だけで発生した。HTTP ステータスコードは 1054 が返ってきたりする。なんか変な gem でも入れてしまったかなと休みの日に動作検証したりしていたんだけどついぞ分からなかった。

SQL 弱者なので気がついてなかったんだけど、2月15日の commit で Site モデルに新しいフィールドが追加されていた(Add default markup in admin/site/edit · 2243dc5 · lokka/lokka ※この機能便利すね)。なので bundle exec rake db:migrate しないといけなかったわけだった。ローカルで動いている開発環境(データベースは SQLite)では Migration なんて行ってないんだけどエラーは出なかった。本番は MySQL で動いていて、こちらでだけエラーが出るようだった。

しかしいざ migrate しようとすると失敗する。

bundle exec rake db:migrate
Upgrading Database...
rake aborted!
Invalid default value for 'updated_at'

のようなエラーが出る。updated_at のデフォルト値がおかしいらしい。このときのテーブルの構造を見てみると以下のような感じだった。

mysql> desc entries;
+-----------------+--------------+------+-----+---------------------+-----------------------------+
| Field           | Type         | Null | Key | Default             | Extra                       |
+-----------------+--------------+------+-----+---------------------+-----------------------------+
| id              | int(11)      | NO   | PRI | NULL                | auto_increment              |
| user_id         | int(11)      | YES  |     | NULL                |                             |
| category_id     | int(11)      | YES  |     | NULL                |                             |
| slug            | varchar(255) | YES  |     | NULL                |                             |
| title           | varchar(255) | YES  |     | NULL                |                             |
| body            | text         | YES  |     | NULL                |                             |
| type            | text         | NO   |     | NULL                |                             |
| draft           | tinyint(1)   | YES  |     | 0                   |                             |
| created_at      | timestamp    | NO   |     | 0000-00-00 00:00:00 |                             |
| updated_at      | timestamp    | NO   |     | CURRENT_TIMESTAMP   | on update CURRENT_TIMESTAMP |
| frozen_tag_list | text         | YES  |     | NULL                |                             |
| markup          | varchar(255) | YES  |     | NULL                |                             |
+-----------------+--------------+------+-----+---------------------+-----------------------------+

調べてみたところ MySQL の Mode が NO_ZERO_DATE になっている場合、MySQL は timestamp 型のフィールドのデフォルト値に 0000-00-00 00:00:00 みたいな値を設定することを許さないらしい。 mysql - Invalid default value for 'create_date' timestamp field - Stack Overflow

検証用に別にテーブルを用意して bundle exec rake db:setup してみたところ、以下のような構造のテーブルができた。

mysql> desc entries;
+-----------------+------------------+------+-----+---------+----------------+
| Field           | Type             | Null | Key | Default | Extra          |
+-----------------+------------------+------+-----+---------+----------------+
| id              | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| user_id         | int(11)          | YES  |     | NULL    |                |
| category_id     | int(11)          | YES  |     | NULL    |                |
| slug            | varchar(255)     | YES  |     | NULL    |                |
| title           | varchar(255)     | YES  |     | NULL    |                |
| body            | text             | YES  |     | NULL    |                |
| markup          | varchar(255)     | YES  |     | NULL    |                |
| type            | varchar(50)      | NO   |     | NULL    |                |
| draft           | tinyint(1)       | YES  |     | 0       |                |
| created_at      | datetime         | YES  |     | NULL    |                |
| updated_at      | datetime         | YES  |     | NULL    |                |
| frozen_tag_list | text             | YES  |     | NULL    |                |
+-----------------+------------------+------+-----+---------+----------------+

created_atupdated_atdatetime 型になるらしい。なので以下のような ALTER 文を実行した。

mysql> alter table entries modify column created_at datetime, modify column updated_at datetime;
mysql> desc entries;
+-----------------+--------------+------+-----+---------+----------------+
| Field           | Type         | Null | Key | Default | Extra          |
+-----------------+--------------+------+-----+---------+----------------+
| id              | int(11)      | NO   | PRI | NULL    | auto_increment |
| user_id         | int(11)      | YES  |     | NULL    |                |
| category_id     | int(11)      | YES  |     | NULL    |                |
| slug            | varchar(255) | YES  |     | NULL    |                |
| title           | varchar(255) | YES  |     | NULL    |                |
| body            | text         | YES  |     | NULL    |                |
| type            | text         | NO   |     | NULL    |                |
| draft           | tinyint(1)   | YES  |     | 0       |                |
| created_at      | datetime     | YES  |     | NULL    |                |
| updated_at      | datetime     | YES  |     | NULL    |                |
| frozen_tag_list | text         | YES  |     | NULL    |                |
| markup          | varchar(255) | YES  |     | NULL    |                |
+-----------------+--------------+------+-----+---------+----------------+

これで最新のコードをデプロイしても真っ白画面になることはなくなった。以前遭遇した更新時に created_at の値が更新されてしまう問題 もフィールドの型が timestamp だったのが原因なのだと思う。SQLite から MySQL への移行は一筋縄では行かないことが分かった。

DataMapper はソースコード内の記述内容から動的に Migration を行えるけど、ActiveRecord みたいに $APP_ROOT/db/ ディレクトリに Migration ファイルを作ってくれたりしないので DB スキーマの変更が必要なことに気がつきにくい。便利だけど不便な感じがする。Rails で $APP_ROOT/db/ 以下にアホみたいにファイルが出来ていくの嫌だと思っていたけど、スキーマ変更に気がつかずコードをデプロイしてウェブアプリケーション停止みたいな自体は防げると思った。

ブログ書こうと思ってパソコン開いて「ついでに最新版の変更を取り込むか」とかやるとデプロイできなくなったりして書きたかった記事が書けず残念な感じになる。はてなブログでブログ書いてて画面が真っ白になったらひとでくんさんに不具合報告して直してもらえば良いので楽だと思う。

| @Mac/iPhone

先日、自宅の MacBook Pro (Mid 2009) 内の MacVim kaoriya で quickrun が実行できないと書いた(Homebrew で入れた MacVim だと quickrun できる)。どうも Python が原因らしいことがわかっていた。

Mac に入っている Python のバージョンが古いのかなと思い(でもそれだとなぜ CUI 版の Vim で quickrun できるの説明がつかない)、 Homebrew で Python を入れてみた。なんか symlink を作成できなかったとかエラーが出たので brew link --overwrite python とかやってかなり無理気味に入れてみた。しかし相変わらず MacVim kaoriya から qiuckrun を実行すると MacVim が落ちる。

そもそも会社の MacBook Pro や自己所有の MacBook Air ではこのような現象は起こらないため、この Mac に入ってる Python が異常なのでは? と思い至った。

確認してないのでテキトーなんだけど、おそらく、この Mac に入ってる Python は 32bit OS 用のやつが入ってたような気がする。というのは /usr/local/bin にあるいくつかの symlink が以下のように 2008 年に作成されたファイルを指していたから。

https://resources.portalshit.net/930-pythons.png

かつて NOKIA の携帯を使っていたときにゴニョゴニョするために Mac OS X 用の Python パッケージをダウンロードしてインストールしていて、それが 32bit OS 用のバイナリだったために問題が発生しているのかも知れないと思った。試しに python.org から 64bit OS 用の Python パッケージをダウンロードしてきてインストールしてみたら無事 MacVim kaoriya で quickrun できるようになった。

CPU が Core Solo、Core Duo の Mac だったら 64bit でしか動作しない Mac OS X (Lion 以降の OS)をインストールできないのでこんな問題には遭遇しないのだろうけど、自宅の MacBook Pro は Core2 Duo なので 32bit OS でも 64bit OS でもインストールできてしまうためにこのような問題に行き当たってしまったのだと思う。

あと OS のアップグレード時にアーカイブインストールではなくクリーンインストールを選んでいたらこのような問題には遭遇しなかったかも知れない。写真や音楽などだけ TimeMachine から復旧するようにして、Mac をアップグレードするときは OS そのものはまっさらな状態でインストールする方が良いということが分かった。アプリケーションもいまは Mac AppStore があるので昔より前の環境に戻すのが難しくない。

ただ Adobe 製品のライセンス認証解除とかは OS のクリーンインストール前にぬかりなく行っておかないとシリアルキーが通らなくなって死ねそう。

そういうわけで、Snow Leopard 時代から Core2 Duo CPU の Mac を Mountain Lion まで Upgrade して使っていて MacVim の quickrun が動かない人は Python をインストールし直すことを試してみてください。

| @散財

一昨年、会社を変わったときに Happy Hacking Keyboard Professional 2 を買った んだけど、貧乏性のためなかなか会社に持っていって使うという気にならず、会社では3年前に買った HHK Lite2 を使い、Pro の方は家で使っていた。

しかしよくよく考えると家でコードを書く時間よりも会社でコードを書く時間の方が圧倒的に長いわけで、一番長くコードを書く時間を一番良いキーボードととともに過ごした方がよいのではないかと考えを改めて HHK Pro を会社で使うことにした。

連休明けの火曜から HHK Pro でコードを書いていて一週間が終わったところだけど、会社で毎日8時間以上使うことで初めて良さが分かったような気がする。Lite に比べてしっかりしている。Lite はカチャカチャとうるさいけど Pro は激しくキーを叩いても静かだ。それなのに押したときの反発は Lite の方が重く、Pro の方が軽い。Lite はカチャカチャしていておもちゃのようで、音を聞くだけで疲れる。

キー配列に関しても、HHK Pro はただの US 配列とは異なっていて、チルダキーの位置や Control キーの位置が一般的な US 配列よりも利用しやすい位置に置いてある。正直プログラミングしやすい。

HHK Pro を使うことで困ることと言ったら、それ以外のキーボードを利用したくなくなることだと思う。家でも職場でも HHK Pro が使いたくなる。自分の場合は HHK Pro を二つも買えるような財力はないので、そもそも HHK Pro を買ってしまったのが失敗だったのかも知れない。毎日 Amazon を開いてため息をつきながら HHK Pro をカートに入れたり戻したりしている。

| @技術/プログラミング

最近、cap deploy がしんどい。

5938930a9f1e1eb35812dbe10b5c1fd8.png (768×416)

こんな感じで、デプロイすると CPU の使用率が高まってしまう。Unicorn が暴走してるっぽい。シンボリックリンクとかはちゃんと置き換わってるんだけど、プロセスが古いままで、サイトの出力が新しくデプロイしたものに置き換わらない。こうなると cap deploy:restart とかやっても無反応で、ssh でログインして Unicorn を一旦停止し、手動で Lokka を再起動しないといけない。

拡散お願いしますアドベントカレンダー2012参加したとき、記事を公開してすぐサイトが落ちてしまって「やっぱりスモールマイクロインスタンスでは人気サイトポータルシットを運用するのは無理なのかな」と思ったのだけどどうもアクセスが集中して落ちたわけではないっぽい。

何なんだろう。

| @散財

指定暴力団清貧会会長なので2012年の消費活動を振り返ろうと思います。買って良かったものベスト3をご覧ください。

3位 無印良品の肌着

天然素材にこだわったぬくもりクルーネック長袖シャツ 紳士・M・杢カーキ

3年くらい前からヒートテックを着て冬を過ごしていた。しかしヒートテックは窮屈だしちくちくしていて着心地がよくなく、さらにすぐ伸びてだらだらになってしまうので正直微妙だと思っていた。今年は偶然無印良品で見かけたこの肌着が安くなっていたので試しに買ってみたら、大変暖かくて良かった。気に入ったのでもう一枚買って二枚でローテーションを組んでいる。ユニクロのヒートテックとの違いは、生地の厚みと柔らかさにある。ユニクロのヒートテックは生地が薄くて締め付けられる感覚があるけど、この無印良品の肌着は生地に厚みがあり、締め付けはゆるく、心地よく着られる。暖かさもヒートテックよりも暖かいと思う。氷点下の阿蘇でもこの肌着と厚手のラガーシャツとナイロンパーカーの三枚で外出できた。買ってよかったと思う。

2位 携帯ウォシュレット

痔瘻になって手術後とかシートン法の輪ゴムをつけてる間とか、肛門周辺が阿鼻叫喚になっているときはウォシュレットがないとつらい。自宅は古い賃貸住宅なのでウォシュレットがついてなくて、痔瘻になった後は半泣きになりながら血だらけの肛門を拭いていた。そんなときに伊藤直也さんのブログを読んで携帯ウォシュレットなるものの存在を知り、すぐさま注文した。最初は半信半疑だったんだけど、普通に使える。手で水が当たる部分を調整できる分、便器に備え付けてあるやつよりも便利かもしれない。水の強さ調節もできるし、満タン時は23秒間放水できる。ただ便器備え付けのやつと違って温水ではなく水しか出せないので冬場はつらい。でもこいつがなければ俺の肛門は崩壊してたと思う。買ってよかったと思う。

1位 ソニーの Bluetooth ヘッドホン

これは嫁さんに買ってもらった。Bluetooth なのがとてもすばらしい。ワイヤレスヘッドホン、初めて買ったけど想像以上に良かった。実は二年くらい前から Kleer という規格のヘッドホンを狙ってはいた。当時は Bluetooth は音質の劣化がひどく実用に耐えないという意見を目にすることが多かった。Kleer は Bluetooth の後継規格で、まだ普及がいまいちなため出力側に送信機をつけないといけなかった。TH-WR700 という TDK 製のを買おうかと思ったのだけど、せっかく無線のヘッドホンを導入するのに送信機を取り付けなければならないというのが気にくわなかった。Mac につないで使うのならそれでもよいかもだけど、外で iPhone で使うときにヘッドホンジャックに送信機をつけるなんてあり得ないと思った。 MDR-1RBT は Bluetooth の Version 3.0 という規格に対応していて、よく知らないんだけど音質がいいらしい。また無線接続時は再生される周波数の帯域が20Hz-20000Hzまで落ち込むらしいんだけど、Sony が開発したナントカという技術によって劣化した音質を頑張ってなかなかよいとこまで復元するらしい。どうしても Bluetooth の音質に不満がある場合は、付属のケーブルを使うことで兄弟製品の MDR-1R と同じ音質で再生できるらしい。これも良い。自分は高音難聴でどうせ8000Hz以上の音は聞こえないので自分にとっての可聴域はカバーされているし、音質面で MDR-1RBT には全く不満がない。音質重視のヘッドホンだけどマイクとかついていて、電話のヘッドセットとしても使えるし、充電が micro USB でできるのも良い。ヘッドホンがオーディオの世界に閉じこもるのやめてデジタルガジェットの方に歩み寄ってきた感がある。買ってよかったと思う。

以上、2012年買って良かったものベスト3でした。

| @Mac/iPhone

MacBook Air すごく速くて使いやすいけど、自分のものではなくて家庭の所有物みたいな感じになっててあまり使わせてもらえなかった。悔しいので3年前に買った MacBook Pro 15” の HDD を外して SSD に入れ換えてみた。嘘みたいに速くなった。買ったのはこれ。いまは 512GB のやつも3万円くらいで買える。

一緒にディスクケースも買ったけど、間違って SATA じゃなくて IDE のやつを買ってしまって買い直さないといけなかった。あとポリカ MacBook の頃はトルクスドライバーは T8 でよかったのに(本当は恐ろしいMacBookのHDD換装)、最近の MacBook Pro は T6 じゃないとダメらしいので注意が必要。折角 SSD が手もとに届いたのにトルクスドライバーが無いために換装作業が出来なくて悶々としてしまった。

取り換え作業自体はそんなに難しくない。ただし光学ドライブ外して SSD と HDD の二ストレージ構成とかにしようとすると難しいと思う。TimeMachine からの復旧は NAS からやったら信じられないくらい遅かったし(300GB のデータ転送に三日くらいかかった)、Adobe 製品のライセンシングが機能しなくなってものすごくめんどくさいことになったのでオススメしません。ポリカ MacBook で HDD の換装やったときのデータの取り込みは、ディスクケースに入れて USB 接続した旧 HDD からやったけどこういう問題には遭遇しなかった。こっちの方が速くて安全だと思う。

ちなみに円高終わるっぽいので換装を考えてる人は早めに SSD 買った方が良いですよ。

使った道具