ひょんなことから島根の自治体の方と知り合いになり、島根県が企業やコミュニティの合宿を誘致しているという話を聞きました。

合宿またやりたいなあ。島根まだ行ったことないし行ってみたいなあ。という気持ちからゆるデブのメンバーに相談したところ、反応がよかったので色々詳細詰めて、ゴールデンウィークを利用して島根に行くことにしました (\( ⁰⊖⁰)/)

内容については、すでに iR3 さんがブログに書いてくれています。

島根県松江市美保関町北浦海岸でyurufuwa開発合宿 - iR3’s diary

感想

全体を通じて、とても楽しい合宿でした!また行きたい!

島根の田中さんや井上さん、民宿の中村屋さんにいろいろご配慮&差し入れいただいて快適な合宿になりました。

4泊5日の合宿でしたが、2日は移動日(ゴールデンウィークなので調度良い時間のチケットが取れなかった><)に当て、2日もくもく、1日はアクティビティにあてました。

東京から二時間かからず島根までいけるので、思ってたよりも移動は楽でした。

もくもく

開発風景。和室だと腰が辛くなるので、椅子があると嬉しいですとお願いしたところ、人数分の椅子と机を用意していただけました。お陰でとても快適に開発できました。

DSC06202

コードを書くのに疲れたら、窓ごしに海を眺めてHPを回復させることができます。

あとは海辺でコードを書いたり。

IMG_3854

美味しい海鮮系ご飯を大量にいただきました。

アクティビティ

アクティビティはシーカヤックと、浜辺でのバーベキューでした。溢れるリア充感。

DSC06329

DSC06318

DSC06399

DSC06402

DSC06404

合宿中、ちょうど@fukayatsu氏の誕生日があったのでケーキを食べました。

IMG_3885

最終日の一枚。

IMG_3041

まとめ

合宿場所の候補として、島根はちょうオススメです!近場の合宿に飽きたら島根に足を伸ばしてみると良いとおもいます (\( ⁰⊖⁰)/)

LOCAL Community Summit とは、 地方の技術者やコミュニティの取り組みを、地元だけではなく東京で発表してみよう! 私達の地域の楽しさを、他の地域の技術者にも伝えよう! 地元を離れ首都圏で活躍している技術者や、いろんな地域のコミュニティと繋がろう! というテーマのもと、LOCALとして初の東京開催となるIT勉強会イベントです。

LOCAL Community Summit 2015 - LOCAL Community Summit | Doorkeeper

「いろんな地域のコミュニティ」の1つとして、ginza.rb の紹介LTをしてきました (\( ⁰⊖⁰)/)

スライド見ただけだと内容はわかりにくいかと思いますので簡単に補足。

LOCALは、いろんなコミュニティの人が集まるメタコミュニティ!という話を聞いていたので、運営的に気をつけている点を中心にしつつ ginza.rb の紹介をしました。

ginza.rb は他のコミュニティの良い所を吸収しています。例えば自己紹介用の文章をプルリクエストで集めるのはよちよち.rbのやり方を参考にしたし、初参加の人に一言感想をもらうのはP4D、KPTで振り返りをするのはSendagaya.rbで実施しているのを見て真似をしてみました。

さらに毎回少しずつ改善を重ねて楽しいミートアップになるようにしています。その中でも、ミートアップ中に idobata を併用して、情報を補足するやり方はうまくワークしているように思えます。

「ginza.rb らしさとは何か?」と聞かれたら、そういうところなのではないかと思います。

先月、heroku の推しサーバが unicorn から puma に変わったという発表がありました。unicorn だとスロークライアントの影響を受けやすいというのが理由なようです。

もう少し詳しく調べてみましょう。

そもそもスロークライアントってなに

その名の通り遅い回線のクライアントです。3G環境のモバイル端末などが該当します。

「unicorn だとスロークライアントの影響を受けやすい」とは

unicorn はプロセスモデルのサーバであり、blocking I/O モデルを採用しています。つまり、クライアントとの通信中プロセスが専有されるということです。

例えば unicorn がワーカプロセスを3つ立ち上げていて、そこへ通信完了に10分かかるようなスロークライアントが3つ接続されたら…、続くクライアントはスロークライアントの通信が完了するまで実行を待たなければならなくなります。プロセスの数をもっと増やせば対応できますが、それはその分メモリやサーバ台数、最終的には月額のサーバ費用に影響を与えます。

unicorn はなぜそんな設計になっているのか

unicorn は、「ひとつのことをうまくやる」unix哲学に則っており、その上で "バックエンドの" アプリケーションサーバとして作られています。

つまり、nginx などのリバースプロキシを前面にたてるのを前提とした作りになっているわけです。

The Philosophy Behind unicorn

リバースプロキシを使うと、unicorn はレスポンスをリバースプロキシまで届ければよくなります。リバースプロキシはたいてい同一ネットワーク内にあるので、とても早く通信できます。スロークライアントが通信するのはリバースプロキシです。これにより、スロークライアントが unicorn のプロセスを長時間専有するのを防ぐことができます。

nginx & unicorn は、heroku 以外の Rails アプリケーション環境では現時点で一番多い構成なのではないでしょうか。

heroku にはリバースプロキシはないのか

ないようです。ただ、heroku の HTTP Routing のドキュメントを見ると、1MB まではレスポンスをバッファしてくれるようですね。

HTTP Routing | Heroku Dev Center

puma に変更したら全て解決するのか

この発表このへんの文章を見ると、puma にしたらオールオッケーなように読めてしまいますが、そんなことはありません。

この記事 の Multi-threaded blocking I/O の箇所を読むと分かるのですが、確かにスレッドベースのサーバを採用すると、1スレッドがスロークライアントで専有されても別のスレッドが処理を受け持つことができます。ただし、全てのスレッドがスロークライアントと通信したら、結局同じことです。

同じメモリ量でも、プロセスベースのサーバより、スレッドベースのサーバの方が作成できるスレッド数が多いので、スレッドベースのほうがスロークライアントに強いということは言えると思います。

puma にすることによるリスク

puma はスレッドベースのサーバです。ということは、アプリケーションの書き方によっては race condition を引き起こす可能性があります。普通に Rails アプリケーションを書けばスレッドセーフになるはずですが、その辺りをよくわかっていない初心者が安易に手を出すのは危険なのかなと思います。

よくわからない人は Working With Ruby Threads を読みましょう。

unicorn の方が優っていることもあります。この間 ginza.rb で unicorn や puma などの Rack サーバのベンチマーク結果を比較をしました。結果としては、大量アクセス時の処理としては unicorn の方が puma よりも安定している印象でした。

「puma が不安定だ」とは思わないのですが、安易に「herokuが推奨してるからこれからは puma だ! unicorn はオワコン!」とならないようにリスクについても書いてみました。

まとめと雑感

基本的に、リバースプロキシのない heroku を使うのであれば、現時点では puma が適していると思います。しかしその場合はスレッドセーフなコードを書くよう気をつけなければなりません。

また、heroku 以外の環境ではリバースプロキシが使えるため、puma にすることのメリットは(heroku ほどには)ないと言えます。まだまだ nginx & unicorn の天下が続くのではないでしょうか。

リバースプロキシ内蔵のプロセスベース(スレッドベースにもできる)のサーバである raptor (passenger 5) 正式版ががそろそろリリースされます。以前の ginza.rb でベンチマークをとった時は beta2 だったのでまだまだ不安定な印象でしたが、正式版になって安定したら、heroku 環境での鉄板サーバになるかもしれません。

取り急ぎこのブログ(heroku & lokka)を passenger 5.0.0.rc2 にしてみました。このブログは特にアクセス数が多いわけではないので高負荷時の安定性などはわかりませんが、とりあえず普通に動きますね。

自分用のメモ。RubyMotion 3.3。

前提

  • RubyMotion では Java のクラスを Ruby で継承できる
  • ただ、その際はコンストラクタだけは Java で書かないとダメ

単純にコンストラクタを書く用途以外に、「現行のRubyMotionでうまく動かない箇所をJavaで書いて何とか動かす」用途としても使える(バッドノウハウ)。

落とし穴のレシピ

  • コンストラクタでインスタンス変数に値を格納する
  • 当然、Java の方で変数宣言する

この時、Ruby 側でも attr_accessor などを使ってインスタンス変数にアクセスするメソッドを生やすとハマる。なぜか Java の方で入れた値を Ruby 側で見ることができず、 nil になる。

解決策

attr_accessor を消せば OK