oinume journal

Scratchpad of what I learned

2016年の振り返り

まずは今年の1月に書いた新年の抱負を振り返ってみる。

英語を頑張る

技術的なやり取りは苦がなくできるぐらいになっていたいなぁと。会話も文章も両方で。あとブログの英語比率を50%に持って行きたい。あと何か1冊英語の本を最後まで読む。

ブログの英語比率は 6 / 18 で33%だった。12月ぐらいから面倒になってほぼすべて日本語で書いてしまっていたのが敗因。ただ、会社でTOEICを10年振りに受けて、745点だったのでそこそこDMM英会話の成果は出ている気がする。リーディングよりリスニングの方が点がよかったのが嬉しい。

アルゴリズム勉強する

6月までにB+Treeをソラで実装できるようにしたい

未達。algoというリポジトリでアルゴリズムやり直してるけど、ハッシュをソラで実装するのがギリギリできるかぐらいだった。

機械学習を勉強する

ライブラリやフレームワークを使ってちょいちょいできるぐらいになってたい。

これも未達。CourseraのMachineLearningのコース受けたけど挫折…

何かサービスを一つ作る

これはlekcijeというサービス作ったので達成。マイナーなニーズにもかかわらず、リリースしてから1ヶ月で40人の人に使ってもらえてるのが嬉しい!ただ、サービスを作っていると無限にやりたいことが出てきて、本来やりたかった勉強の時間をついつい開発の時間にあててしまうのが悩みどころ...

今年こそDocker

仕事とプライベートでは軽く使っているので達成かな。基本的なところをもっと理解しないと。

抱負以外でやったこと

Web+DB Pressの特集書いた

Web+DB Press Vol.93に前職の同僚とSQLの高速化について記事を書いた。ものを書くのは人生で2回めだったのである程度はわかっているつもりだったけど、想像を絶する大変さで5月の休日をほぼ全部これに費やしてしまった。でもSQLのチューニングについて自分の理解が甘いところも理解を深めることができたのでありがたい機会だった。あと、最近の執筆活動はGitHubで原稿の管理ができるので進捗管理や共同作業は楽だなぁと思った!

Advent Calendar

Advent Calendarを3本書いた。Herokuのヤツはまだ欠けているところがあるので、これからでもネタ考えて埋めたい。

OSS活動

tomahawkを少しメンテナンスしたのと、他の人のライブラリに軽くプルリクしたぐらい。来年はもっとちゃんとした機能追加や改善のプルリクを送りたいなぁ。

プログラミング言語

プログラミング言語についてはずっとGoをやっていて、もうかれこれ2.5年ぐらいGoを書いてる。Pythonをプライベートでもほぼ書かなくなってしまったのでこっちもリハビリしないと。

まとめ

今年は歳のせいか地味に体を壊すことが多くて、体調回りで苦労することが多かった。運動してないせいで体力が落ちているのが一番問題だと思っているので、来年はランニングまたは筋トレを本腰入れてやるつもり。一方で、家族は大きな病気をすることもなく元気に過ごせていたのが一番ありがたかった。2017年は健康を第一に、体力をつけて仕事も私生活もハードワークできるようにしたい。

2016年に読んだ本

本当は「2016年に買ったもの」という記事を書こうと思ったけど、日用品以外で買ったものがあまりなかったので読んだ本(技術書以外)を晒してみる。

ヒューマンエラーを防ぐ知恵 ミスはなくなるか

ヒューマンエラーを防ぐ知恵 ミスはなくなるか (朝日文庫)

ヒューマンエラーを防ぐ知恵 ミスはなくなるか (朝日文庫)

仕事でケアレスミスを連発していた時期になんとかせねばと思い購入。

  • 実際の事故を分析するには、原因の分類よりも原因の結合を考えるべき。事故は人間・機械・職場の態勢などが複合して起こる。
  • 決別遷移(事故につながる状態への遷移)を全て洗い出し、この決別遷移に至らないように予防する
  • 小さな事故が大きな事故に発展しないようにする

などなど。メモを見返すと本当に参考になる。

新版 大統領にしらせますか?

新版 大統領に知らせますか? (新潮文庫)

新版 大統領に知らせますか? (新潮文庫)

昔よく読んでいたジェフリー・アーチャーの小説。知人と昔好きだった作家の話になり懐かしくてつい購入。息もつかせぬ展開でおもしろい。

学力の経済学

「学力」の経済学

「学力」の経済学

話題になっていたので読んでみた。

  • ご褒美で釣るのはいいのか悪いのか?
  • 褒めてのばすのは本当にいいのか?
  • テレビやゲームは学力に悪影響があるのか?

などなど、気になるトピックがたくさんあって今後の子育てをする上でめちゃめちゃ参考になった。

池上彰の「日本の教育」がよくわかる本

池上彰の「日本の教育」がよくわかる本 (PHP文庫)

池上彰の「日本の教育」がよくわかる本 (PHP文庫)

子供が生まれたせいか、最近教育業界が気になるので購入。日本の教育回りの仕組み(学校、教育委員会、日教組)がわかりやすくまとめられていてよかった。海外との比較もされていて、例えば、教育大国のフィンランドの給食はパンとスープだけなのに、日本の給食は栄養バランスがよく考えられていてすごいらしい。

週刊ダイヤモンド 2016年11/12号

週刊ダイヤモンド 2016年11/12号 [雑誌]

週刊ダイヤモンド 2016年11/12号 [雑誌]

「疲労の正体」という特集が気になったので購入。

  • 疲労の正体は乳酸ではなく活性酸素。人間は細胞内で酸素を燃焼させてエネルギーにするが、この時生成される副産物が活性酸素。運動などによる負荷の場合は筋肉の細胞が、ストレスなど精神的な負荷の場合は脳や神経細胞がダメージを受ける。
  • 疲れているのに眠れない、は自律神経中枢の機能の乱れ。自律神経は緊張、運動、覚醒機能を司る交感神経と、リラックス、休息、睡眠機能を司る副交感神経の二つで構成され、スイッチすることで体内のバランスを保っている。昼間は交感神経、夜には副交感神経に切り替えるが、ストレスや明るい光にさらされると副交感神経に切り替えられずに疲れているけど眠れないという状況になる。
  • 好きな趣味ややりがいのある仕事をしているときは疲れを感じない。これはやりがい、達成感、喜びを感じていると前頭葉が疲労伝達物質をかき消してしまい、疲れを感じなくなってしまう

暴露:スノーデンが私に託したファイル

暴露―スノーデンが私に託したファイル―

暴露―スノーデンが私に託したファイル―

NSAやCIAで働いていたエドワード・スノーデンが暴いたNSAによる国民監視について、膨大な資料をまとめたもの。シチズンフォーという映画を見て、とても面白かったのでこの本も読んでみた。映画は2時間という時間の制約上あまり語られていなかった監視の実態が淡々と書かれている。FacebookやGoogleやMicrosoftがNSAに協力してバックドアを仕掛けたり、自社のサーバーにNSAがアクセスできるようにしているらしい。もうインターネットが信じられなくなった。

シチズンフォー スノーデンの暴露(字幕版)

シチズンフォー スノーデンの暴露(字幕版)

  • ローラ・ポイトラス
  • ドキュメンタリー
  • ¥2000

Herokuの好きなところ

これはHeroku Advent Calendar 2016の13日目の記事です。個人的にHerokuを使い続けてはや3年。仕事でヘビーに使っているわけではないけど、Herokuの好きなところを挙げてみます。

ディプロイが楽

ディプロイがgit push heroku masterで済むのは本当に楽。一昔前だったらディプロイスクリプトを用意しなくてはいけなかったけど、コマンド一つでディプロイできるようになった。というか今だとGitHubでmasterブランチにマージさえすれば勝手にディプロイされるようにもできる。

アドオン

これも月並みな感想だけど、heroku addons:add でアドオンを追加して、アプリケーションに組み込むことができるのが楽。さらに、heroku addons:open <addon>を実行するとブラウザが立ち上がってログイン状態でそのアドオンの管理画面に行けるのも地味にすごい。

ちなみに自分がどんなアプリケーションでも使っているアドオンはpapertrail。↓のような感じでブラウザからログを検索できて、S3にもアーカイブ保存できたりして便利。

papertrail

無料で使える

1つのWebアプリを動かすのであれば、24時間稼働させても無料枠内でタダで使えるのも個人的には嬉しい。

イマイチなところ

もちろんHerokuも100%完璧ではなくて、イマイチなところもある。個人的に不満なのは以下。

  • 日本リージョンが無料では使えない
    • US-eastかEUしかリージョンが選べないので、日本からだとレイテンシがやっぱり気になる。Heroku Private SpacesにはTokyo regionもあるけど有料なので業務じゃないと使えなさそう。
  • CDN的な機能がない
    • addonで組み込むことはできるけど、これぐらいはデフォルトであると嬉しい

最後に

Herokuを使い続けて思うのは「アプリケーションの開発に集中できる」という点。この目的のためにすごく色んなところを頑張ってるんだろうなぁと思う。PaaSはなかなか収益的に厳しそうだけど、素晴らしいサービスなのでこれからも頑張って欲しい!

WebアプリケーションのE2EテストをGoで書く

これはGo Advent Calendar 2016の18日目の記事です。今回はGoでE2Eテストを行うためのライブラリagoutiについて書きます。

GoでE2Eテストを書く理由

WebアプリケーションのサーバーサイドをGoで書いている場合、GoでE2Eテストを書くメリットとして

  • JavaScriptが得意ではないエンジニア(自分)でもE2Eテストがガリガリかける
  • E2Eテスト実行時のカバレッジが取れる=サーバーのコードのどこを通ったかがわかる

があると思っている。特に2番めの理由が大事で、「E2Eテストを全部回した結果、サーバーのこの部分のコードは通っている」とわかるのはけっこう大きなメリットなのではないかと。どこがテストされている・いないを把握することで、「ここはE2Eテストだと難しいからユニットテストでカバーしよう」というような戦法が取りやすいと思う。

じゃあ具体的にGoでどうやってE2Eテストを書くのか、ということを次に説明する。

Go製WebDriverクライアントagouti

GoにはagoutiというSelenium WebDriverのクライアントがあるので、今回はこれを使う。agouti自体は単にWebブラウザを操作するライブラリなので、あわせてChromeDriverなどをインストールする必要がある。MacにChromeDriverをインストールするのはHomebrewでbrew install chromedriverしてインストールするのが楽で、それ以外のOSではChromeDriverのサイトからダウンロードしてすればOK。

一例として、下記のようなagoutiを使うGoのコードを書いて動かすと、Chromeが起動して https://ifconfig.co/ のページが表示されて5秒スリープする。

    webDriver := agouti.ChromeDriver() // ChromeDriverを使う
    if err := webDriver.Start(); err != nil {
        return err
    }
    defer webDriver.Stop()

    page, err := webDriver.NewPage()
    if err != nil {
        t.Error(err)
    }
    // Navigateで指定したURLにアクセスする
    if err := page.Navigate("https://ifconfig.co/"); err != nil {
        t.Error(err)
    }
    time.Sleep(5 * time.Second)

agoutiでWebアプリケーションをテストする

もう少し実践的な例として、フォームに入力された値を表示する簡単なWebアプリをテストするケースを考える。ディレクトリ構成は

  • cmd: サーバーの実行ファイル用
  • app: Webアプリケーションの本体
  • e2e: E2Eテスト置き場

という感じになっていて、全てのコードはgo-e2e-test-sampleのリポジトリに上げてある。

この、単にフォームで送信された名前を表示するだけのWebアプリケーションのコードはこんな感じ。

そして、E2Eテストのコードはこんな感じ。TestIndex/にアクセスしている。

ポイントとしては

  • testMainでサーバーとChromeDriverを起動
  • TestIndex関数内でwebDriver.NewPageでPageを生成し、Page.Navigateで起動したサーバーのURLにアクセス
  • Page.FindByXPathでHTMLの要素を検索してformをSubmit

というような流れになっている。なお、今回はXPathを使ってHTMLの要素を検索しているが、CSS Selectorを使うFindなんかもある。詳しくはgodocを見れば詳しく書いてある。

そして、このe2e_test.gogo testコマンドで実行すると、Chromeが立ち上がってテストが実行される。

$ go test -v ./e2e

カバレッジを取ってみる

では次にカバレッジを取って、どの部分がE2Eテストによって実行されているのかを調べてみる。go testの引数に-coverpkg-coverprofileをつけて実行する。

$ go test -v -cover -coverpkg=./app -coverprofile=cover.out ./e2e

これでcover.outにカバレッジのためのファイルができるので、go tool coverでHTMLとして表示してみる。

$ go tool cover  -html cover.out

ブラウザが立ち上がって下記のような画面が表示されるので、今回のE2Eテストで実行されているコードがひと目でわかる。

go_tool_cover_html

まとめ

  • agouti便利
  • go testでE2Eテストを実行できるようにしておくとgo tool coverなどのGoエコシステムがそのまま使える

Better Heroku Schedulerを探したらCustom clock processesにたどり着いた

これはHeroku Advent Calendar 2016の11日目の記事です。

HerokuではHeroku Schedulerというcronのようなサービスがあるのですが、使い込むうちに「Daily, Hourly, Every 10 minutesの単位でしかジョブを動かせない」という制限がつらくなってきたので、より良い代替であるCustom clock processesを試してみたという話。

Custom clock processesとは?

clockというプロセスを立ち上げっぱなしにして、そのプロセス内でスケジューリングされたジョブを実行する仕組み。Heroku Schedulerは実行される時だけプロセスが立ち上がるけど、clockの場合は常にプロセスが常駐する。

各言語のScheduler

HerokuのCustom clock processesのドキュメントで触れられているのはJavaとPythonの2種類だけど、各言語ごとにだいたいcron likeなSchedulerが用意されている。今回は自分が慣れているPythonのAPSchedulerを試してみた。

APSchedulerの設定

まずPythonのモジュールのインストールのために、requirements.txtというファイルを用意する。

echo APScheduler > requirements.txt

次にProcfileに以下を追記する。

clock: python clock.py

ここで指定されているclock.pyがジョブの設定が書かれたファイルになる。どのように記述するべきか、詳しくは公式のドキュメントに書かれている。以下は1分毎にhello worldを出力する設定。

from apscheduler.schedulers.blocking import BlockingScheduler
import subprocess

scheduler = BlockingScheduler()

@scheduler.scheduled_job('interval', minutes=1)
def timed_job():
    print("Run notifier")
    subprocess.run("hello world", shell=True, check=True)

scheduler.start()

最後に、APSchedulerを動かすのにはPythonが必要なので、buildpackを追加。

heroku buildpacks:add https://github.com/heroku/heroku-buildpack-python

あとはclock.pyをコミットしてディプロイすればOK。

ローカルで試したい場合

ローカルで試してみたい場合は以下のようにAPSchedulerをインストールして、clock.pyを直接呼び出せばOK。

pip install -r requirements.txt
python ./clock.py

Custom clock processesとFree Dyno Hours

Heroku Schedulerは実行する際にプロセスが起動されて、プロセスが動いていた時間だけ無料分のFree Dyno Hoursを消費するのだけど、custom clock processesはworkerのようにclockプロセスが常駐する形になるので、起動していた時間分だけFree Dyno Hoursを消費するようなので注意が必要。webと併用していると倍速でFree Dyno Hoursを消費するので気をつけましょう。

まとめ

Heroku Schedulerよりきめ細かい時限式のジョブを定義したいときはCustom clock processesを使おう!