RubyKaigi 2014 Day1

[RubyKaigi 2014](http://rubykaigi.org/2014/) の 1日目まとめ

# CRuby Committers Who's Who in 2014

- http://rubykaigi.org/2014/presentation/S-TomoyukiChikanaga
- ちかながさん
- svnアカウント数: 85 (bot込)
- 去年の6月以降にコミットしてるのは 50
- RubyKaigi2014で発表するのは 15人
- 発表順に紹介
  - ktsj -- power assert 作った人
  - keiju -- ruby開発中のmatzと同僚。名前候補を出した
  - kou -- rexml, xmlrpc, activeldap メンテナ。clearcode社長


# Building the Ruby interpreter -- What is easy and what is difficult?

- http://rubykaigi.org/2014/presentation/S-KoichiSasada
- ささださん

## 10周年

- YARV
- 日本Rubyの会
- Rubyist Magazine

## 何やってきたか

- YARVは2004/1/1から作り始めた
- Ruby 2.1 で世代別GCを取り入れた
- Understanding Computing の監訳したよー


## Rubyインタプリタの開発において何が簡単で、何が難しいのか

- クオリティの指標
  - Reliablity / availability
  - High Performance
  - Low machine resource
  - Good Compatibility (互換性)
  - Extensibility (拡張性)
- これらはだいたい Performance とのトレードオフになる
  - 何とのトレードオフが存在するか、をよく知ることが大事
  - トレードオフに打ち勝つ。 両方良くする第3の解をみつける

### Ruby Performance: Serial execution

- VM作ったり、JIT作ることは実はさほど難しくない
  - 人間が管理可能な状態で維持しながら、パフォーマンス最適化などを施していくこと、が難しい
  - テストの結果で F が一個出たって、全然壊れてないじゃん！最後まで実行できてるじゃん！
  - 似たようなコードがたくさん出てくる (→メンテナンスしずらくなる)
    - コード生成機を作ることで回避
- 積極的な最適化
  - 様々な方法論が存在するが...
  - Rubyの動的な性質（メソッド再定義、eval内部からローカル変数アクセス）を使った時に、最適化が無に帰する
- Interoperability with C codes
  - Ruby VM は C の中で起きたことをうまく知ることができない。
  - Javaのライブラリは、殆どJavaで書かれている事実
    - Ruby でそれをやったのが Rubinius
  - rubyで書き直す？ Cにアノテーション付ける？
    - でも人間は忘れるもの。annotationつけ忘れたらバグになってしまうので....

### Ruby Performance: Parallel execution

- 並列スレッドを提供するだけであれば、簡単。。だが
- 書きやすい、扱いやすい、並列スレッドプログラミングの仕掛けを作るのは大変
  - デバッガとか？
- スレッドプログラミングって難しい
 - 他スレッドと状態を共有しているので、様々なこうりょが必要
- free vs GC
  - 分かってる人がfreeした方が早い。けど、そこに頭使わなくて良いGCが良いよねーと。
- スレッドよりも...
  - より良い IPC の方が楽だったりしない? (Processで分離されるわけだし)
  - Multiple virtual machine
  - "Owner threads" for each objects
- いずれにせよ
  - うまく導入しないと「非決定的な挙動がプログラマを殺す」
  - 「Rubyらしく書ける」と「スレッドっぽい何か」をうまく共存させたい

### Ruby Performance: GC

- GCアルゴリズムを作るのは簡単
- バグなく、ちゃんと作るのが大変
  - アルゴリズム以外のケアが大変
  - 例えば、ライトバリアテクニック。既存コード全てに手を入れることは出来ない
  - デバッグ大変。GCのバグでプログラムが止まったとしても、その原因は遠い過去に起こったものだったりする

### Development Community

- Committer なるだけなら簡単だけど
- Ruby Developer になるのは難しいよね
  - モチベーションを持って、継続できるか？
- Ruby Hacking Guide は、やっぱりバイブル


# Symbol GC

- http://rubykaigi.org/2014/presentation/S-NarihiroNakamura
- nariさん NaCL
- Symbol ?
  - 人間が読みやすい形式の一意の識別子
- `:symbol`
- A pitfall of symbol
  - 全てのシンボルはGCされない
  - ユーザ入力をシンボルに変換するコードを書いてしまうと脆弱性となってしまう
  - Railsの脆弱性
    - 他の言語では、SymbolはGCされる？ → 実装依存。実装が仕様です。
    - EmacsLisp では `unintern 'foo` で不要なものを明示的に消せる


## Ruby の Symbol 実装

- `"sym".to_sym` すれば freeze した String Object を作る
- global_symbols ハッシュテーブルに freeze した String Object の object id を入れる
  - C 世界では id を使う。Ruby世界でSymbol使うには id2sym 的なAPIを呼ぶ必要ある
  - id比較だけなので早い

## なぜ今までのRubyはsymbolをGCできなかったか

- `:foo` を作る。その ID は `002` となった
- C拡張には、symbol ID を内部に保持するライブラリが存在する
- Ruby世界的には `:foo` の参照が無くなったらGC出来そう
- GC したら `:foo` が無くなる
- その後でまた `:foo` を作る。そのIDは先ほどとは違うものになる `040`
- symbol同士の比較はIDで比較するので `:foo` と `:foo` が一致しないことになる..

## どうやって解消した?

- Immortal Symbol
  - 今までどおり? のSymbol
  - こっちはこれまでどおりGCされない
- Mortal Symbol
  - IDを持たないSymbol
  - `"sym".to_sym` のようなメソッドで出来る
  - GCされる
  - 作ろうとしたときに、既に Immortal Symbol が存在した場合
    - Immortal Symbol をそのまま参照して使う
  - Mortal Symbol から Immortal Symbol に変換される場合
    - `define_method("foo".to_sym){}` みたいなの
    - メソッド定義には ID が必要なので、今までどおりの ID 付の Symbol に変換される
    - A new pitfall is comming!
      - 「Symbol GC が入ったから、Symbolは全部GCされる」は間違い
      - これまで同様に注意しなければならない場面は存在する
        - sym2id & id2name を使うのではなく、 sym2name (新API) を使うべし
        - 前者は Mortal -> Immortal 変換が発生してしまう


# Continuous Delivery at GitHub

- http://rubykaigi.org/2014/presentation/S-RobertSanheim
- 人多すぎであるw
- Rob Sanheim

## What is Cont. Delivery?

- いつでもデプロイできる状態となっていること
- 顧客に価値を速やかに届けなければならない
- Heart bleeed のような脆弱性対応のスピードにも現れる
- Release あたりの期間が長いとフィードバックが得られるまでの時間も長くなる
  - Change Request, QA, Bugs, Deploy, Test, Build, ...
  - 年に1-2回のサイクルとか話にならんほど遅すぎる
  - 半年で片手の指以上の回数リリースするんだ -> それが CD だろ

## How ?

- Automation
- Tests
  - ちゃんとテスト書けよ
  - 60k test/models
  - 34k test/integ
  - 31k test/controllers
  - 21k test/lib
  - :::
  - ruby app 158l
  - ruby test 167 k
  - test /app ratio: 1.06
- Pull Requests
  - Pull-Req コメントのライブアップデート入れたよ、って話してる
  - ..?
- FeatureFlags
  - ↓みたいなのを入れて、先にスタッフ向けに機能をリリースする
```
  def new_feature_enabled?
    logged_in? && self.staff?
  end
```
  - 大丈夫なことを確認できたら書き換える
```
  def new_feature_enabled?
    true
  end
```
  - `live_updates_enabled?` もそうやった
  - 顧客(まず最初は社員)に対して素早く価値を届ける。その先に一般ユーザが居る
  - (Cookpad の Chanko も似たようなこと出来るなーと思いながら聞いてた)
- 長生きするブランチを少なくすべし
  - GHだとRails2から3に上げたのは長かった
  - rails3-redux で作業してた
  - 時間かかりすぎ & ２つメンテするのやってらんない
  - masterで作業することにした
  - rails2/rails3 は環境変数で切り替えできるようにしてた `RAILS3=true` すげえ
  - 巨大なプルリク作るよりも、if/elseで上手く区切って、小さいPullReq出すほうが楽だよーという感じ？
  - masterが激動しないなら、別ブランチのほうが管理楽そうだけどなｗ
- ChatOps
  - HU-BOT
  - `/deploy github/my-feature to production`
  - `/deploy github/my-feature to branch-lab`
  - `/deploy github/my-feature to production/fe1,fe2,fe3`
  - capistrano とか
- Post Deploy
  - 様々なメトリクス取得してる
  - レスポンス時間とか、負荷状況のモニタリング
  - twitterも観てる

## 参考

- http://martinfowler.com/bliki/FeatureToggle.html

# What's wrong with your app?

- http://rubykaigi.org/2014/presentation/S-KeikoOda
- Heroku technical support の中の人 SF在住
- Herokuの H12 エラー
  - タイムアウトエラー (30sec)
  - Herokuが悪いんじゃなくて、ほとんどはユーザアプリの問題
  - あとは外部API/サービスの問題
  - 時間がかかるリクエストがあると、キューに積まれる

# Introduce Oracle enhanced adapter for ActiveRecord, another choice for your Rails database.

- http://rubykaigi.org/2014/presentation/S-YasuoHonda
- MySQLユーザが思った以上に多い@会場
- PostgreSQLが強い @ Rails Survey ? の結果
- Cross the border
  - 大江戸RubyKaigiの青木さんの発表に触発された

## Who

- Yasuo Honda @yahonda
- Oracle DBA (仕事)
- Oracle enhanced adapter for ActiveRecord (趣味?)
  - 3rd party の ActiveRecord Adapter
  - Rails 2.3* - 4.1 supported
  - Rails 4.2 support (in progress, 79failures/errors)

## Oracle with Rails

- Web系よりは、社内ツール的な
- 既存OracleのDBに合わせて、Railsを書くような使い方が多い
  - Rails way から外れたDBにマッピングさせるgemもある

# Hypermedia: the Missing Element to Building Adaptable Web APIs in Rails

- http://rubykaigi.org/2014/presentation/S-ToruKawamura
- 発表資料: http://www.slideshare.net/tkawa1/rubykaigi2014-hypermedia-the-missing-element
- @tkawa
- sendagaya.rb の人

## WebAPIの分類

- 蜘蛛の巣のようなAPI
  - public api
  - uncontrollable
- 蜘蛛の糸のようなAPI
  - private api
  - internal use
  - (for single page app ?)
- RESTにするか否かは要件次第
- 変化は避けられない。変化しなければならない。
- 変化に適応できるWebApiを作らなければ。

## Breaking change は何故起こるのか

- API 仕様をマシンリーダブルな形式で記述すれば、endpointが変わってもok?
  - うーむ
  - Breaking change が起こるのは、密結合だから。
- 疎結合にすればよい。どうするか。
  - 脱・ハードコード
  - クライアントが次になにをすべきか？ がかわるAPIにしよう。
    - next キーがそんざいすれば... とか。
  - ブラウザはバージョン上げても壊れないよね？ Non-Breaking change だよね？
- microdata ... SEOとかで使われるけど、データ構造化・埋め込みに使える
- JSON と HTML の違いは、LInk, Form を含むか否か
  - HAL, JSON+... とか
  - Hypermicrodata.gem
  - microdata と Link と Form をサーバサイドでJSONに変化する

## 疎結合にするために

- `model.to_json` やめて、view model ちゃんと使いましょう
  - model が露出するので密結合になる
- API作るときにも、WebUIのように状態遷移を意識してLink, Formを意識しましょう
- 参考資料: webを支える技術


# "Gem of this Week" - building culture and making gem

- http://rubykaigi.org/2014/presentation/S-TakumiMiura
- 発表資料: https://speakerdeck.com/mitaku/rubykaigi-2014-gem-of-this-week
- mitaku
- ドリコムの人
- ソシャゲのサーバ側作ったり

## 理想の開発

- フットワーク軽く
- → 技術的負債が増えるよりも早く、減らさなければならない
- 開発速度を早める。品質を高める。
- そのためには...
  - 複雑なビジネスロジックを共通化したい...
    - rubygems.org には公開しにくい
    - 社内にgem server作ってる
- 重複したコードをgemにする
  - ユーザエージェント情報のパースとか (軽い処理だけど、みんなが個別に書くのはアホらしい)
  - アプリ内課金処理みたいなビジネスロジックも
  - 死活監視 komachi_heartbeat
    - rails_engine でマウントすればokなRailsアプリ監視
    - https://github.com/mitaku/komachi_heartbeat

## 理想の開発を実現するため: Building Culture

### gem作るときの障壁を取り除きたい

- 今週のgem
  - gemを作るのが特別なことではない、と
- private gem server にアップロード
  - 間違えて rubygems.org に公開しちゃいそう
  - そもそも公開手順をドキュメントにするよりも、専用ツール、コマンド作っちゃえ
    - rake release を削除したので、間違えることもない

### 自由

GitLab使ってる
- Project横断で自由にコードを見ることができる
- 自由にリポジトリを作成可能

### キッカケ作り

- 社内ツール自作サークル！
- 利用しているgemをチェックして更新を通知してくれる
  - https://gemnasium.com/
  - http://tachikoma.io/
  - 最新gem使用率をランキングにしてる (→アクティブに開発しているプロダクトは、更新する圧力になる)
- next: 出せるものはrubygems.org に

## 作ったgemの紹介

- capistrano-drecom-deploy
  - 秘伝のタレ解消..
- rails_security_patch_cve_*
  - 大人の事情でRails更新できないときに...
- drecomssh
  - mirakuiさんの ec2ssh の様な
- ordered_find
  - rails で `User.where(id: [1,3,2])` が順序を保持した結果を返してくれる
  - 普通だと `User.where(id: [1,3,2]).map(&:id)` は `[1,2,3]` になる