isucon6 の予選に出てきた


タイトル通りはじめてisuconに参加しました。チームメイト2人が体調不良ということもあり、体調を整える重要さも気づきました。
結果から言うと、タイトル通り予選に出場して終わったという感じでした。

まず、Azureということで運営の方から用意された、VMを作成するテンプレートをデプロイした所 over limit quata
というエラーが出て何度やってもデプロイできない状態でした。
原因は練習用に立てていたVMをそのままの小押しておいたのですが、そのVMのCPU数と競技用のVMのCPU数の総数が無料枠からオーバーしているようでした。練習用のVMを削除したらその後は難なく立ち上げられました。

初期スコアを図ったら4000超位がスタートでした。
Rubyの実装に変えたり、nginxでの静的配信に変えたりして細いインフラのチューニングをやっていましたが、、そんなに効果はなく。。。

ざっくりプロファイリングの仕方などは事前に確認していたのでalpとかを使ったり pt-query-digest を使ってボトルネックを探すというのを初めた所、遅いのは トップページ(/) や キーワードページ(/keyword) というところは判明しました。

DBにインデックスはるなどの微調整できるかと考えていたりしましたが、特にこれと言って効果が出るのもなく。。。
チームメンバーがキャッシュ機構を入れるということで直接サーバの方でアプリの方を修正してくれました。

その間、、自分のチューニングポイントはある程度やりきった感があって、どうしたもんかと悩んでいる時間で、実装のソースを見て、実際に動かしたいと思ったけど、サーバのアプリはチームメンバーが触っているし、下手に触るとコンフリクト起こしそうだしということで、早くからローカルで開発できる環境を整えるべきだと思いながら、ただただコード見ていました。
(このあたりはだいぶ準備不足でどのようにやっていくかなどは事前に話しておくべきだったと思います。)

キャッシュの機構ができて導入してみるものの、一瞬スコアが出るなどもありましたが、Failが多発するなどなかなかうまくいかないうちにタイムアップとなりました。
今回の問題はミドルウェアレベルのチューニングはあまり効果がなかったので、アプリをきちんと修正できるような環境をさくっと作れるような準備などをもっと考えておけばよかったと思いました。

来年もあったら参加したい!!!ありがとうございました!
そしてチームメンバーありがとうございました!

RubyKaigi 2016に行ってきた


RubyKaigi 2016 に行ってきた。
京都開催ということで美味しいものもいっぱいあったし、なにより懇親会で「まつもと」という日本酒がとてもうまかった。
技術的ことはもっと身につけないとという意識が高まったし、英語のトークが資料を見ながらふんわり理解できるくらいなのがだいぶ悔しい感じだったので、どっちももっと頑張らないとという意識が高まったのが参加したメリットだったかも。

まつもと

以下からは簡単なメモ。

スライドなどは以下のサイトにまとめられていました。動画も後日公開されるかもです。

「RubyKaigi2015」全公開済みスライドまとめ #rubykaigi | TechStars Blog

Binding(How to create bindinngs 2016)

GObject Instropection を使うのが良い
C拡張Lib だけど Bindingではないものもある。
Ruby FFI(libffi implを使ったライブラリ)

require 'gi'
GI.load

Scalable Job Queue System Built with Docker

Cookpad Barbeque というジョブキューの発表でした。
とてつももなく参考になる内容だった!!

Modern Black Mages Fighting in the Real World

fluentd1.4系の黒魔術のすごさ。。。

昨今のWebフロントエンド開発環境を調べてみた(2014年ごろ)


メモっていたのを、、忘れてしまうので公開します。

参考

資料

Javascript周り

Grunt

タスクランナー(Rakeのようなもの)
JavaScriptの連結や圧縮、SCSSなどのコンパイルをするときに使う。それだけじゃなくファイル更新をトリガに一連のタスクを自動実行するなどにも使える.

glup.jsというのもある

gulp.js チートシート – Qiita
【Gulp.js入門】新鋭フロンエンド・タスクランナーツール を試してみました。 | Developers.IO

bower + require.js

bower.jsonに利用するライブラリを書いてbower installすると.bowerrcに書かれたライブラリを一括ダウンロードできる。
インストールしたライブラリを<script src=“”>で読み込むものを一個ずつ指定するのは面倒なときにrequire.jsを利用する

mocha + expect.js

BDDスタイルテストフレームワークであるmocha、マッチャーを提供するアサーションライブラリのexpect.js

sinon.js

mockやstubなどテストダブル(ダミーオブジェクト)を利用するときに使用する。
「Spy」「Stub」「Mock」「Fake Timer」「Fake XHR」

karma

testの自動実行(遠隔実行)ライブラリ。テストの更新を検知して複数のブラウザでテストを自動実行してくれたりする。
Karma(元Testacular)を使って簡単にテストを実行しよう

testemというのもある

phantom.js

WebブラウザなしでJavascriptの実行などが行える。コマンドラインから扱えることが便利。ただwebkitエンジンのみ
JavaScriptの自動テスト <=だけどphantom.jsのことが書かれている

backbone.js + underscore.js

backbone.jsとその依存ライブラリのunderscore.js。
使ったこと無いから以下を参考にしよう。

jquery

いつものですね。

jquery-template or ejs

テンプレートエンジン

foreman

プロセスを管理。Gruntとアプリサーバなどを同時に管理したいときなど


CSS周り

sass + compass

sassですね。sassの拡張compassですね

twitter bootstrapなどのCSSフレームワークはいろいろある。

http://liginc.co.jp/web/html-css/html/21108

Font Awesome

http://fortawesome.github.io/Font-Awesome/examples/
フォントのアイコンライブラリ


特記

Middleman

上に書いたようなGruntとかを使った環境のオールインワンパッケージ
http://hokaccha.github.io/slides/middleman_frontend_dev/

pub / sub のメッセージングモデルの考え方について


関連記事

実装編

require.jsを利用した場合のディレクトリ構成

/
├── sources/
│     ├── css/
│     │   ├── lib/
│     │   └── sass/
│     ├── js/
│     │   ├── lib/
│     │   ├── src/
│     │   │    └── require.config.js
│     │   └── test/
│     │        └── require.config.js
│     ├── node_modules/
│     ├── Gruntfile.coffee
│     ├── config.rb
│     ├── karma.conf.js
│     └── package.json
│     
└── public/
      ├── api_stub/
      │   └── recent_sites.json
      ├── css/
      │   ├── common/
      │   ├── lib/
      │   └── 各種CSSファイルやディレクトリ
      ├── js/
      │   ├── common/
      │   ├── lib/
      │   ├── 各種JSファイルやディレクトリ
      │   └── require.config.js
      └──img/
          ├── common/
          └── 各種画像ファイルやディレクトリ

require.jsの実践編

以下の通りhtmlでrequire.js関連ファイルを読込む

<script src="/js/require.config.js"></script>
<script src="/js/lib/require.js" data-main="/js/users/index.js"></script>

上記のタグで読み込んでいる箇所は require.js を読み込んだあとに data-main のjsファイルを読み込むことができる。

ここでは /js/require.config.js では実際に require メソッドを使ってconfigを実行していなくて、設定のハッシュだけを作成している状態。

data-mainで指定している各ディレクトリのjsの中で require メソッドで実行して、require.config.js 内のハッシュ設定部分を実行させている。

npm Tips

以下のコマンドにてnpmインストールしすつつpackage.jsonを更新できる。

# package.jsonのdevDependenciesに追加される
npm install hogehoge --save-dev
# package.jsonのdependenciesに追加される
npm install hogehoge --save

gulpとかnpmのこととか by A Memorandum <=ここにもnpmの使い方。 –save-devの説明が簡単に載っている

gulp

# globalに入れる
npm install -g gulp

# 各プロジェクト配下に入れる
npm install --save-dev gulp
npm install --save-dev gulp-concat

Browserify

Browserify: それはrequire()を使うための魔法の杖 – Qiita
JavaScript – BrowserifyでBackbone.jsを使うときのjQueryの解決 – Qiita

フロントエンドの開発でファイルプロトコル(file://…)ではなくHttpプロトコル(http://)を使う


※ローカルにApacheを立ててバーチャルホストを作って云々という話ではありません。


背景

フロントエンドの開発において、htmlファイルをサクッとブラウザで開けば(file://…)、Javascript, css が動くというのはとてもメリットだと思うのですが、実際にサーバにアップロードしてアクセスするときにはほぼ100% Httpプロトコル(http://)でアクセスすると思います。そういった環境をローカル開発でも使うといいと思います。

file://hoge/fuga/index.html」などをブラウザ確認するとファイル内で imgタグ, scriptタグ, linkタグ などは以下のように 相対パス で書くことになると思うのですが、それをサーバにアップする時に 絶対パス に直すということをしている人は多いと思います。

<img src="img/hoge.png">
<link rel="stylesheet" href="css/hoge.css" />
<script src="js/hoge.js"></script>

その際、いちいち変換するのは面倒くさいので、pythonやrubyで動かせる簡易Webサーバを立ち上げてHttpプロトコル(http://…)で開発をしましょうという話です!

前提条件

  • Python or Rubyがインストールされているマシンを用意する(Macなら大丈夫。windowsはpythonとか入っていても起動できるかは謎)

  • ファイル構成

/tmp/workspace/
├── index.html
└── js/
    └── app.js
<html>
<head></head>
<body>
<h1>テストページ</h1>
<script src="/js/app.js"></script>     <!-- 絶対パスapp.jsを指定している -->
</body>
</html>

Pythonを使った例

ドキュメントルートとなるディレクトリへ移動する
$ cd /tmp/workspace

Webサーバを立ち上げる(3000はポート番号なので開いているPortなら何番でもOK)
$ python -m SimpleHTTPServer 3000

ブラウザを立ち上げて http://localhost:3000 へアクセスすると index.html が表示されます!

Rubyを使った例

ドキュメントルートとなるディレクトリへ移動する
$ cd /tmp/workspace

Webサーバを立ち上げる(3000はポート番号なので開いているPortなら何番でもOK)
$ ruby -run -e httpd . -p 3000

ブラウザを立ち上げて http://localhost:3000 へアクセスすると index.html が表示されます!

PHPを使った例

ドキュメントルートとなるディレクトリへ移動する
$ cd /tmp/workspace

Webサーバを立ち上げる(3000はポート番号なので開いているPortなら何番でもOK)
$ php -S localhost:3000

ブラウザを立ち上げて http://localhost:3000 へアクセスすると index.html が表示されます!

さらなるTips

Python、Rubyの場合は デフォルトの index.html がない状態でフォルダ指定してアクセスすると、DirectoryIndexが表示されファイルリストを見ることができます。
今回の場合は以下のように js フォルダにアクセスすると

http://localhost:3000/js

以下の様な画面が出力されます。(Rubyを使った場合)

Ruby-webrick-directoryindex

参考サイト

ワンライナーWebサーバを集めてみた -Qiita

[rails]Rakeタスクでのtask定義の「:environment」引数について


Railsのジェネレータで生成したタスクのrbファイルを見ているとRakeタスクを定義するところで少し疑問に思ったことがあった。

railsのジェネレーターで以下のとおりにタスクを作成する。

% rails generate TASK_FILE_NAME TASK_NAME

例)
% rails generate hoge test

例)のように実行すると lib/tasks/hoge.rb ができて testというタスクが定義される

namespace :hoge do
  desc "TODO"
  task test: :environment do
  end
end

タスク定義のところで「:environment」 という引数が渡されているが、どういうこのことなのかを調べてみた。

「RailsでオリジナルRakeタスク作成からRSpecテストまで」 の記事の中に以下の一文があったので実際に試してみる。

:environment は モデルにアクセスするのに必須

引用:RailsでオリジナルRakeタスク作成からRSpecテストまで


lib/tasks/hoge.rb を以下のように変更する。

(Userモデルのデータは別途用意していることが前提)

  1. testタスク :environmentの引数を渡さない
  2. test_twoタスク :environmentの引数を渡す
namespace :hoge do
  desc "does not huve environment args"
  task :test do
    puts User.first
  end

  desc "has environment args"
  task test_two: :environment do
    puts User.first
  end
end

それぞれを実行する

  • 1.testタスク :environmentの引数を渡さない
% rake hoge:test
rake aborted!
uninitialized constant User
…省略

=> なんか「uninitialized constant User」という例外でエラーになる。


  • 2.test_twoタスク :environmentの引数を渡す
% rake hoge:test_two
# <User:0x007fadd5f68a80>

=> ちゃんとユーザを取得できている

まとめ

RailsでRakeタスクを使ってActiveRecordのモデルなどを扱うときは 「:environment」引数を渡して上げると良い!

さらに、実行時にもenvironmentを呼ぶことが出来るようだ

rakeタスク実行時に environment をよんでから hoge:test を呼ぶ

% rake environment hoge:test

コードは読んでなく検証しただけなので、もっと詳しくは調べないとなー