読者です 読者をやめる 読者になる 読者になる

handlename's blog

コード片など

ブログ移転しました

実はもう1年以上経っているのだけど、ブログをはてなブログから自前ホスティングのものに移転した。

http://blog.handlena.me/

移転先の関連エントリ:

自前ホスティングとは言いつつもそれは移転当初のみで、いまはAWSのS3で静的サイトホスティングしている。

移転の理由は自分でブログをいじりたくなったから。 はてなブログに何か不満があったわけではない・・・強いて言えば独自ドメインの設定にPro登録必須、ということくらいか。

自分で管理するのが面倒になったらまた戻ってくるかもしれない。

Macbook Pro Early 2015をセットアップするときにやったこと

メインマシンがMacBook Air 2011から MacBook Pro (Retina, 13-inch、Early 2015)に変わったので セットアップ時にやったことをメモしておく。

MacBook Airの時のメモはこちら

Airの時は結構細かく書いているが、 今回は設定ファイルはBittorrent Syncで共有するだけだし アプリはhomebrewで入れるだけなのであまりやることがない。

いつもの

  • CapsLockをCtrlに変える
  • マウスカーソルの大きさを変える
  • システムフォルダ名を日本語に
  • コンピュータ名を変更

やり方は先に書いたAirのエントリを参照。

タップでクリック

Airのに書いてなかったけど変更してる。 システム環境設定/トラックパッドタップでクリック。 クリックよりタップのほうが楽。

Slack

最初のデータ(主にテキスト)のやりとりに使う。 調べ物などは環境が整っている既存のマシンでやったほうが早いので、 旧マシンで調べてSlackで適当なチャンネルに書いて新マシンで実行なり保存なり。

メールで送ったりファイル共有したりsynergyを使ったりなどほかにも方法はあるが、 履歴が残る方法を使うとあとあと調べるときによさそう。

そのほかAppStoreから色々入れる

AlfredはPowerPackを使いたいのでbrew caskで入れる。

locateを有効にする

初期状態ではlocateコマンドが使えない(DB更新サービスが動いていない)ようなので、 手動で有効にする。 色々ファイルを入れる前にやっておくのがよさ気。

$ sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist

homebrew

http://brew.sh/

これがないと始まらない。 なんかいつの間にかサイトが日本語対応しててびっくりした。

homebrewで色々入れる

brewdlerにおまかせ

$ brew tap Homebrew/brewdler
$ brew brewdler

いまのBrewfileはこんなの

brew brewdle dumpしただけなので余計なのも入ってる。

Google Chromeはcaskで入れると1Pasword連携が使えなかった。 Chrome/Application以下に配置されていないといけないらしい。 Chromeだけ例外というのも悔しいので、この機会にSafariをメインに使ってみる。 (でもデベロッパツールChromeのが便利なのでインストールすることにはなりそう・・・)

Dockを空っぽにする & 自動的に隠す

基本的にDockは使わないので必要最小限にする。 無効にできればなお良い。 あとで調べてみよう。

Sparkをつかわない

アプリケーションの切り替えにSparkを使っていたが、 BetterTouchToolのglobalなキーボードショートカットに登録することにした。 アプリ起動時のベゼル表示がなくなるのがちょっとさみしい。 Spark自体はYosemiteでも問題なく動く。

Ukeleleをやめる

キーボード配列の変更にUkeleleを使っていたが、 YosemiteではUkeleleで変更した配列は特定のアプリケーションでは使えないらしい。 (強制的にUSなどのデフォルト配列に切り替えられてしまう)

代わりにKarabinerでキーを置き換えることにした。 private.xmlはこんな感じ

いつもどおり(?)のDvorak + C <-> K + 数字反転。

数字の反転(たとえば1をタイプすると!が、Shift+1をタイプすると1が入力される) の設定を一応書いたものの、他の修飾キーと組み合わせると元の文字が入力されるのでいまいち。 すべての組み合わせを定義すればいいのだけれども・・・。

Chromeを使わない

メインブラウザとしては使わない。 homebrewの項目で書いたとおり。 Safariをどうやって使っているかはまた別の機会に書く。

ブラウザはSleipnirOperaFirefoxChromeSafari と数回引っ越ししている。

Bittorrent Sync 2.0

いつの間にかメジャーバージョンアップしてた。 VPS上でも動かして、常に同期されるようにしている。 Linux用のクライアントは設定ファイルで同期するためのsecretを指定できるのだけど、 2.0ではこのsecretが発行できなくなった。

かわりにWebUIから同期用のコードを入力すればいい・・・のだけど、 セットアップ当時の最新版であるv2.0.105ではCSSファイルが含まれていなくて UIがまともに表示されずに詰む。 しょうがないので古いバージョン(v2.0.85)を探してきてそれを使っている。

いまはv2.0.120が出ているのでそれでは直っているかもしれない。 (けど面倒なので試していない。ChangeLogがあれば・・・)

アカウント名が違うと困ること

とある事情でアカウント名が指定されているので、 マシンによってアカウント名が異なることになってしまった。 つまりホームディレクトリのパスがマシンによって異なることになってしまった。

設定ファイルを各マシンで共有しているので、ファイルパス決め打ちな設定で困る。 たとえばghqのclone先とか($HOMEを使えればいいのだけど・・・)。 とりあえず/Users/{アカウント名}シンボリックリンクを張って対応。


現状はこんな感じか。 だいぶシンプルになった気がする。 思いついたらあとから書き足すかもしれない。

いままでAirを使っていたこともあって、スペック的には新しいProは大変快適。 あとTaptic Engineすごい。 トラックパッド自体が沈み込んでいるとしか思えない。 そのうちiOS端末にも採用されるんだろか。

ただし重い。Airを使っていたからなおさら。 あわせて鞄をAirがぎりぎり入るくらいのショルダーバッグからProが余裕で入るリュックに変えた。 Proをメインにして持ち運ぶ必要がある場合はAirを使う、という運用にすると楽かもしれない。

emacsで使い捨てディレクトリをさくっと作る

open-junk-fileを使うと 使い捨てファイルをさくっと作ることができる。

使い捨てディレクトリも同じようにさくっと作りたい。 ということでopen-junk-fileを真似してopen-junk-dirというコマンドを作った。

https://github.com/handlename/dot-emacs/blob/master/inits/30_open-junk-file.el#L7-15

問題の関数のところだけを抜粋すると、

(defvar junk-file-dir "~/junk")
(defvar junk-file-format-base (concat junk-file-dir "/%Y/%m/%Y%m%d_%H%M%S"))
(defvar my:open-junk-dir-format (concat junk-file-format-base "_"))

;;; open-junk-dir
(defvar my:open-junk-dir-format (concat junk-file-format-base "_"))

(defun my:open-junk-dir ()
  (interactive)
  (let* ((dir-base (format-time-string my:open-junk-dir-format (current-time)))
         (dir (read-string "Dirname: " dir-base)))
    (make-directory dir t)
    (find-file dir)))

いままで~/tmpなどに都度ディレクトリを作っていたが、 これでディレクトリ名に悩む必要がなくなった。

ついでに Emacs で作成した使い捨てファイルを簡単に開く - Qiita を参考にhelmで使い捨てファイルを検索できるようにした。

https://github.com/handlename/dot-emacs/blob/master/inits/30_open-junk-file.el#L17-35

さらについでにagコマンドでjunk-file-dirを検索する関数も定義した。

https://github.com/handlename/dot-emacs/blob/master/inits/30_open-junk-file.el#L37-42

使い捨てファイルがだいぶ使いやすくなった。

highlight-symbolとhydraを組み合わせると捗る

Awesome Emacsという 便利packageリンク集があるのを知って眺めていたら、 表題のhighlight-symbolhydraを組み合わせてみたら捗るんじゃないかと 思って組み合わせてみたらやっぱり捗りそうな感じだったのでメモしておく。

highlight-symbolとは

名前の通りコード内の同一シンボル(と思われるもの)をハイライトしてくれるツール

hydraとは

関連するコマンドを複数定義して、 それらのコマンドを連続して簡単に呼び出せるようにするツール

捗る設定

init.elに以下のように書いて、評価して、

(global-set-key
 (kbd "C-x H")
 (defhydra hydra-highlight-symbol
   (:post (progn
        (highlight-symbol-remove-all)))
   "highlight-symbol"
   ("." highlight-symbol-at-point "highlight")
   ("n" highlight-symbol-next "next")
   ("p" highlight-symbol-prev "prev")
   ("N" highlight-symbol-next-in-defun "next in defun")
   ("P" highlight-symbol-prev-in-defun "prev in defun")))

C-x Hとタイプすれば各コマンド(この場合.npNP)が使えるモードになる。 (「モード」という呼び方が正しいのかどうかは知らない)

C-x Hとタイプした後は各コマンドを単体で連続して使える。 つまりnnnとタイプすれば次々とシンボルをたどることができる。

定義されているキーバインド以外を入力するとこのモードから抜ける。 :postを設定して、抜けるときにハイライトを解除するようにしている。

よくわからないと思うのでスクリーンキャストをどうぞ:

録画の都合上emacs起動時からになっているので半分くらい起動を待つ時間になっております:p 録画用に軽い設定を用意すればいいのかもしれない。 asciinema初めて使ってみたけど便利。

・・・抜けるときにハイライトが解除されてないことに気づいちゃった人もいると思いますが、 なんでかターミナルで動かすとhighlight-symbol-remove-allが効かないんです。 普段はEmacs.appを使っていてそちらでは問題ないので深追いはしない。

hydraのREADMEに載っているzoomやGoto-errorは普通に便利そうなので後で試す。

追記 2015-02-20 10:00

Emacs.appの方でもhighlight-symbol-remove-allが効かなくなっていた・・・ 別のパッケージと干渉している可能性もある? あとで調べる。

tmuxのcopy-pipeとsplit-windowを組み合わせると捗る

  • tmux 1.8

以前こういうエントリを書いた。

ローカルで使っているtmux.confに以下のような設定を書いて、 選択範囲をnopasteに投げられるようにしていた。

bind-key -temacs-copy C-q copy-pipe "cat | ~/bin/np"

上の例にあるnpというコマンドは、

  • nopasteした後にそのURLを標準出力に出す
  • そのURLをブラウザで開く

というもの。

copy-pipeした場合は標準出力が見られないものの、 ブラウザで開くというのは有効なのでローカルで使っている分には特に問題がなかった。

しかし、リモートでtmuxを使っている場合は ブラウザが開けないのでnopasteしたURLが得られず 無意味な設定になってしまう。

アカウントに紐付いたものリストが見られるような nopasteサービスを使っていればそこから辿れなくはないが、 めんどくさいし今使っている社内nopasteにはそんな機能はない。

とはいえこれが使えないとちょっとしたテキストを 共有するのにすごく不便(一度ファイルに落としてからnpコマンドに食わせないといけない)。

そこでtmuxのsplit-window(ウィンドウの分割)と組み合わせて その場でnopaste先のURLを確認できるようにしてみた。

bind-key -temacs-copy C-q copy-pipe "cat | ~/bin/np > ~/.last_np; tmux split-window -p 1 'less ~/.last_np'"

f:id:handlename:20141209193750p:plain

下の方にピコッと表示される (社内nopasteのURLなのでモザイクだらけとなっております)

ちょっと長いがやっていることは簡単で、 nopasteした後にその結果をtmuxのsplit-windowに渡している。

  • npコマンドの結果(=nopaste先のURL)を~/.last_npというファイルに保存
  • split-windowコマンドで~/.last_npの内容をlessで表示
  • URLが表示できればいいだけなので-pは最小の1に

split-windowは引数にコマンドを指定すると そのコマンドが終了すると同時にペインを閉じる。 今回はlessで開いているので、qを入力すればペインごと閉じてくれる。

いちいちファイルを介さないといけないので無駄な感じもするが、 手を動かさないといけないわけではないし、 履歴を確認できると思えばまあいいかな、と。

cat | ~/bin/np >> ~/.last_np; tmux split-window -p 1 'tail -n1 ~/.last_np' | less

とすればすべての履歴を残すことも。

とりあえず捗る。

flycheck用のgo-vetコマンドを再定義する

わけあってgoamzのコードをemacs上で読んでいたら、 こことかで flycheck経由のgo-vetが次のようなワーニングを出していた。

composite literal uses unkeyed fields

AttributeDefinitionsはsliceだから、なんでunkeyed fieldsと書かれているのかがわからない。 スルーしてもいいのだけど、気になるのでググったら 「-composites=falseするといいよ!」ってあった。 https://code.google.com/p/go/issues/detail?id=6820

というわけでflycheckのcheckerを再定義した。

(flycheck-define-checker go-vet
  "A go syntax checker."
  :command ("go" "tool" "vet" "-composites=false" source-inplace)
  :error-patterns ((error line-start
                          (file-name) ":" line ":" (minimal-match (message))
                          line-end))
  :modes (go-mode))

これで上記のワーニングは出なくなった。

#isucon 4決勝にfujiwara組として参加した感想

順位はこちら。

ISUCON4 本選結果 : ISUCON公式Blog

表題の通り感想がメインです。

結果

  • (2位以上に大差を付けられての)3位だった
  • 推測できたはずのスコアアップポイントに気付けなかった

今年の問題

  • 動画広告配信サービスをいい感じにスピードアップする
  • 動画広告の入稿・配信・レポート機能がある
  • サーバーは3台
  • 残業(開始が遅れたことによる1時間延長)あり

やったこと

@acidlemonさんの記事を読んでもらうのがいいかと。 Cache-Controlを有効にして高qps勝負に持ち込むところまで行けなかったので、 後半はアプリよりもnginxとベンチマーカーのパラメータのチューニングがメイン。

感想など

複数チーム分同時に走らせていた影響か、 ベンチマーカーの結果が乱高下して打ち手が効いているのかどうなのか 判断できなかったのが残念。

とはいえキャッシュを効かせて帯域勝負を脱していれば そんなことには影響されなかったはずなのでベンチマーカーのせいにはできない。

  • ネットワーク帯域を使いきっている
  • 使いきらないためには・・・?
  • 動画を送らないというのはどうだろう?

というところまでは辿り着いたものの、 動画配信を適度に失敗させてスコアを稼ごう、という ちょっとずれた方向に進んでしまった。

一時期33万点というスコアを出したチームがあったが、 スコアのグラフからはすぐ消されてしまったので、 「桁が変わるようなブレークスルーはないのだろう」と決めつけてしまっていた。 (優勝チームはこれを見てスコアを劇的に延ばすポイントを探しはじめたとのこと)

ISUCONだからということで、普通のWebサービスなら普通にやることをやらずに (頭のなかの)ベンチマーカーに対してどうやってリクエストを返すか、 ということに時間を使ってしまったのが敗因ですかね。

順位はともかく出題意図に気付けなかったことがくやしい〜〜!!

運営の皆様、参加者の皆様、お疲れ様でした。 来年もISUCONあるよとのことなのでぜひともリベンジしたいところです。