garbagetown

個人の日記です

@toru_inoue から食洗機を譲り受けた

タイトルですべて言っているけど周辺の知見などを。

TL; DR

  • @toru_inoue から食洗機を譲り受けた (圧倒的感謝)
  • AR アプリで設置シミュレーション
  • らくらく家財宅急便は着払い不可
  • 分岐水栓は自分で取り付けるべき
  • 食洗機は全自動食器棚

経緯

加齢とともに肌から潤いが失われ、かつ家族が増えて水仕事をする機会が多くなり、冬になると手荒れがひどくてハンドクリームを手放せず、漠然と食洗機が欲しいなあと思いつつも安くないし場所も取るので二の足を踏んでいたところ、タイムラインに以下のツイートが流れてきた。

聞けば Panasonic の NP-TR8 という製品で、けっこうデカいけど、ざっと寸法を測ってみたところなんとか設置できそう。

戸棚からシステムキッチンの説明書を引っ張り出して確認すると自宅の水栓はタカギの JG 1230 という機種で、ネットで調べてみると CB-STKB6 という分岐水栓で Panasonic の食洗機を取り付けることができるらしい。

急な話で他に検討漏れがないか不安はあったものの、この千載一遇の幸運を逃すまいと図々しく手を上げた。

準備

@toru_inoue 曰く、念のため電気屋に置き場所や水回り工事の相談をしたほうがよいとのなので、さっそく翌日仕事を休んで (ちょうど有給休暇を取る予定だった) 台所の写真を撮りまくってから駅前の電気屋に行って相談したところ、問題ない模様。

分岐水栓の取り付けを業者に依頼すると一万円くらいかかるらしく、自分で作業する人がどれくらいいるのか聞くと「そんな人はいない。うちの店で買ってくれれば五千円で工事する」と言われた。分岐水栓も一万円くらいするし、自分でやってみないことには費用に値する作業なのかも分からないので、検討します、とだけ言って帰ってきた。

帰宅してアマゾンで分岐水栓を注文した後、もらってきたパンフレットをぱらぱら眺めていたら設置シミュレーション用 AR アプリの存在を知った。

カタログの特定ページを開いて置き、AR アプリを通して見るとそこに食洗機が登場するという、なんと言うか想像の斜め上をいく仕様。

アップストアのレビューには悪いことばかり書いてあるけど、設置イメージを具体的に把握できたし、無駄に風呂やトイレに食洗機を登場させて笑えたし、個人的にはとても良かった。

分岐水栓の取り付けに必要なモンキーレンチとプライヤーは別の友人から借りることにして準備完了。

問題

迅速に配送の手配をしてくれた @toru_inoue から連絡。モノがデカいので家財宅急便になるけど着払いは受け付けていないとのこと。

配送料は四千円程度。いったん立て替えてもらい、後日精算することにした。

設置

で、実際にモノが届いたので設置。結論から書くと分岐水栓は自分で取り付けるべき。

実際に使ったのはマイナスドライバー、ピンセット、プライヤー。モンキーレンチはアゴが小さくて使えず、どこかで何かが固着していた場合を想定して用意したゴムハンマーは使わなかった。

具体的な手順は分岐水栓の取扱説明書と上記ツイートの一連のメンションを参照してもらうとして、若干ハマったところだけメモ。

  • 止水栓がちょっと固かった
    • ご家庭ごとに場所や形状が違うので注意
    • 固さはパワーで解決した
  • バーハンドルも固かった
    • 製品によっては六角ネジなどを外してから引き抜くものもあるので注意
    • 固さはパワーで解決した
  • カートリッジも固かった
    • ネットで調べてみたら外したレバーハンドルを差し戻して引き抜けとあったので、その通りにしたら無事に引き抜けた
  • 分岐水栓の取り付けが少し難しかった
    • ここをミスると水漏れの原因になるので注意
    • きちんとハマっていないと分岐水栓側のハブという部分がくるくる回るので、これが回らなくなるまで軽く前後左右に揺すりながら下に押し込む。きちんとハマるとガチっと音がする
  • 分岐水栓、分岐コックのナットが予想より大きかった
    • あとから知ったことだけど水栓工事のナットは 28mm が標準らしい。モンキーレンチはアゴが 30mm まで開くものを用意する
    • 分岐コック側のナットを押さえるために一本、分岐水栓側のナットを締めるために一本、計二本あるとよい
    • 分岐コック側のレバーを手で押さえ、分岐水栓側のナットをプライヤーで締めることで対応した

なにか失敗すると家中水浸しの即クラシアン案件になる気がしてビビっていたけど、やってみたら思ったより簡単だったし、自宅の止水栓や水栓の知識も得られたので自分で作業して良かった。

ただしパワーで解決する場面が何度かあるので、そっち方面に自信がない場合は大人しく金で解決するのもよいと思う。

感想

雑に述べると最高なんだけど、なにが最高なのかよく考えてみた結果、これは全自動食器棚であるのだなと思い至った。

実際に食洗機を利用してみると食洗機導入前後の食器に関する手順は以下のようになる。

手順 導入前 導入後
1 食器棚から取り出す 食洗機から取り出す
2 使う 使う
3 ざっと水で流す ざっと水で流す
4 洗う ほぼ自動
5 乾かす 自動
6 食器棚に収納する ほぼ不要

食洗機という名前から手順 4 が省略されるのは期待通りとして、5 と 6 も省略されるのは意外な体験だった。

手洗いの場合でも水切りカゴにひと晩ほど放置しておけば乾燥は自動化できるものの、水切りカゴは収納力があまりないので乾燥後はどうしても食器棚に戻す必要がある。一方で食洗機はそのまま食器棚として使える収納力があるので、食器を使った後、ざっと水で流して食器棚に収納しておけばなぜか翌朝にはピカピカになっているという感覚に近い。

以前に洗濯乾燥機を手に入れたばかりで興奮冷めやらない友人が「これがおれの洋服ダンスだ」と言いながら洗濯乾燥機から引っ張り出した洋服に着替えていたけど、あれと同じだと思う。

謝辞

脳が若返るような刺激的な機会を提供してくれた @toru_inoue さんに感謝いたします。後日開催予定のうどん会にて配送料を精算すると共に、謝礼として上質の白い粉 (隠語) を献上したい所存です。

JJUG ナイトセミナーに登壇しました #jjug

はじめて JJUG でお話してきました!

jjug.doorkeeper.jp

発表資料はこちら。

口頭で補足した内容を含めた要約は、なかやまさん のライブドローイングレポート (すごい!) にまとまっています。

当日の会場の雰囲気や togetter を見る限り、お話したかった内容は大体伝わっているようで安心しました。

togetter.com

経緯

五月の中頃に「今度のナイトセミナーで Play Framework について話さない?」とお誘い頂きました。

誰よりもドキュメントを読んでいる自負だけはあるものの、Play2 や Scala の実践的な経験はなく、有意義なお話ができるか不安だったのですが、なかなか得難い機会だったので思い切ってお引き受けすることに。

準備

まず、以下のブログとスライドを復習しました。これからプレゼンやる人は必読です。

やるべきことはイメージできたので、続いて登壇のゴールを考えました。ひたすら考えました。グアムの海にぷかぷか浮かんでいるときも考えていました。

どんな人が、なにを期待して聴きに来るんだろう?どうなったら成功したって言えるんだろう?自分にしかできない話、プレゼン...そんなものあるのか...?本当に引き受けてよかったのか、これ?!ウオオオオアアアアア!!

みたいなことを悶々と考えて、最終的に「Play を正しく知ってもらうこと」をゴールに設定しました。

Play が作られた背景や目的、利点だけではなく欠点も正しく知ってもらって、みなさんが抱えている課題にぴたっとハマったときだけ Play を使ってもらって、それで「Play いいじゃん!」となれば最高だなー、と。

ゴールが決まればあとは資料作りです。

まず使い慣れている markdown と reveal.js で全体の構成を組み立てた後、作業環境の都合上 *1 一度 LibreOffice でスライドにしてから KeyNote で清書。その都度 @gakuzzzz さんにレビューして頂き、的確なご指摘を頂くことができました。本当に、本当にありがとうございます!

当日

計画性がないくせに細かいところが気になる性質が災いして、当日の深夜までスライドいじりに明け暮れていたので、スピーチの練習はゼロ。昼休みに会社の後輩に付き合ってもらったリハーサルはボロボロでした。

これはヤバい!と仕事(幸いヒマだった)そっちのけでスクリプトを書いて自席でひとりぶつぶつと練習しました。台本はスライドと同じくらい大事ということに気付いたのが今回の最大の収穫。

その後、終業時刻をややフライング気味に職場を飛び出して、青山のファミリーマートでスライドを最終調整。思いつきで小見出しスライドに経過目標時間や小ネタを書いてみたのですが、いろいろとリラックスできてよかったです。

本番のお話は...自分ではまずまず落ち着いて話せたと思っているのですが、どうだったんでしょう?録画はなかったようなので、なにかお気付きの点があった方はツイッターなどでお知らせ頂けるとうれしいです。

謝辞

まず、貴重な機会をくださった JJUG のみなさんに感謝します。当日の運営も含めて、本当にありがとうございました。

くり返しになりますが、資料をレビューしてくださった @gakuzzzz さん。何度も拙い資料をご確認頂き、申し訳ありませんでした。がくぞさんの協力がなかったら悲惨な結果になっていたと思います。本当にありがとうございました。

リハーサルに付き合ってくれたポリーさん、イッチー、ありがとう!約束どおり今度お酒をごちそうします。

貴重な時間を割いて私のプレゼンを聴いてくださったみなさん、感想をツイートしてくださったみなさん、懇親会でお話させて頂いたみなさんにも感謝です。頂戴した感想を活かして、次回があれば必ずパワーアップしたプレゼンをお届けします!

最後に、構想段階ではいつもぼーっと考え事をしていて、作業段階では毎晩夜更かししてふらふらしていたダメダメな夫・父親を支えてくれた妻と娘に感謝します。本当にありがとう!しばらく家事に専念します ^^;

*1:自宅は Mac で職場は Windows なので...

Cloud Foundry ワークショップに行ってきた #cfws

04/18 に開催された Cloud Foundry ワークショップに参加してきました。

Open PaaS かつ PlayFramework 対応ということで Ruby で実装されていた頃から名前はよく耳にしていましたが、当時は PaaS をなんとなく制約の多い IaaS くらいにしか捉えておらず、あまり積極的にウォッチしていませんでした。

あれから数年が経って Docker や Spring Boot が登場した現在における PaaS の感触を持っておきたかったことと、なにより Pivotal Japan に行ってみたかったことから、業務をさっさと切り上げて参加してきました。

Introduction

30 分くらいと言いつつ 45 分くらい Cloud Foundry の紹介。

以下、当日のメモから特に印象に残った点。

  • Why PaaS?
    • インフラは PaaS に任せてリソースをアプリ開発に集中する
  • Cloud Foundry
    • OSS
    • エンドユーザ企業や日本企業も Foundation に参加
    • マルチベンダで実装。開発スピードが速い
  • Structure
    • CPI (Cloud Provider Interface) を提供する基盤であればどこでも動く
    • BOSH は超すごいオーケストレーションツール
    • Cloud Foundary はそれらの上で動く Runtime
  • Architecture
    • Go で書かれた REST API ラッパの cf コマンドで操作
    • cf push するとアプリケーションに応じた runtime をくっつけた droplet になって cell にデプロイされる
    • cell では Docker Image も動く
  • Service
    • データベースなどのバックエンドサービスは環境変数を通じてアタッチする
  • HA
    • コンテナ/プロセス/VM/AZ の 4 レベルで高可用性を実現
  • Cloud Foundry of Pivotal
    • PWS (Pivotal Web Services) : AWS 上で動作する web サービス。利用メモリ単位で課金
    • PCF (Pivotal Cloud Foundry) : private/public クラウドで動作する商用パッケージ。リッチな GUI など豊富な付加価値
    • PCF Dev : ローカルに PCF 環境を構築する Vagrant イメージ。メモリ 8GB 以上を推奨

ベンダロックインされない OSS 版 Heroku という印象ですが、自分で構築/運用するのはなかなか手強そう。大人しくフルマネージドな PCF の導入を検討した方が良さそうです。

WorkShop

@making さん恒例のサバイバルワークショップ。ある程度 Spring Boot を触っておかないと dependency をダウンロードしている間に置いていかれますw

お品書きはこちら。

  • Pivotal-Japan/cf-workshop: Cloud Foundry Workshop
    1. 事前準備 / Prerequisite
    2. 簡単なアプリケーションをデプロイ / Deploy hello world
    3. バックエンドサービスの利用 / Use backend service
    4. スケールアウト / Scale out application
    5. ログの転送 / Forward logging
    6. Blue-Greenデプロイ / Blue-Green deployment
    7. PCF Devを用いたローカルCloud Foundry環境

上記 1. は事前に済ますようあらかじめ連絡があり、当日は時間の関係から 2. から 4. まで実際に手を動かし、5. から 7. までは説明とデモでした。

実際に手を動かした部分では、やはり OSS 版 Heroku という印象。Heroku を使ったことがあれば、すんなり触ることができます。Spring または Play アプリケーションでのみ利用できる Auto Reconfigure という仕組みで Redis 接続先が自動的に切り替わるのが便利でした。

Blue-Green デプロイは、知識として知っているのと実際に目にするのとでは随分印象が違って、これぞクラウドという感じでした。オンプレシステムの移行案件で死んだ経験があったりすると涙なしでは見られないと思います。複数台のサーバがじわじわ移行していく Scaleover も面白かったです。

まとめ

12 Factor App を満たすクラウドネイティブなアプリケーション開発は今後ますます重要になっていくことを再確認しました。最近話題のマイクロサービスアーキテクチャと合わせて少しずつエンタープライズの世界にも浸透してくると思われるので、リードアーキテクト的な立場にいるエンジニアは三回目以降が開催されたら参加されることをおすすめします。

ただ、そんなマイクロでクラウドなアプリをどこで動かすかは状況次第かなと思います。大規模サービスをコア業務としているのであれば PCF を導入するメリットが十分にあると思いますが、小中規模の請負開発ではフィットしない場合もありそうです。

PCF がもっと広まると PWS の東京リージョンができて、そこで運用するという道も見えるかもしれません。少しでも興味を持った方は、まずワークショップに参加して、60 日間の試用期間を使い倒してブログを書きましょう!

象の虫を踏んだ話

大人の事情で古い CDH 5.1.2 を素の設定で使うと Reducer で OOME が出たり出なかったりする。

2016-02-12 00:58:44,134 WARN [main] org.apache.hadoop.mapred.YarnChild: Exception running child : org.apache.hadoop.mapreduce.task.reduce.Shuffle$ShuffleError: error in shuffle in fetcher#1
    at org.apache.hadoop.mapreduce.task.reduce.Shuffle.run(Shuffle.java:134)
    at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:376)
    at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:167)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:415)
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1554)
    at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:162)
Caused by: java.lang.OutOfMemoryError: Java heap space
    at org.apache.hadoop.io.BoundedByteArrayOutputStream.<init>(BoundedByteArrayOutputStream.java:56)
    at org.apache.hadoop.io.BoundedByteArrayOutputStream.<init>(BoundedByteArrayOutputStream.java:46)
    at org.apache.hadoop.mapreduce.task.reduce.InMemoryMapOutput.<init>(InMemoryMapOutput.java:63)
    at org.apache.hadoop.mapreduce.task.reduce.MergeManagerImpl.unconditionalReserve(MergeManagerImpl.java:297)
    at org.apache.hadoop.mapreduce.task.reduce.MergeManagerImpl.reserve(MergeManagerImpl.java:287)
    at org.apache.hadoop.mapreduce.task.reduce.Fetcher.copyMapOutput(Fetcher.java:411)
    at org.apache.hadoop.mapreduce.task.reduce.Fetcher.copyFromHost(Fetcher.java:341)
    at org.apache.hadoop.mapreduce.task.reduce.Fetcher.run(Fetcher.java:165)

OutOfMemoryError: Java heap space という文字を見て脊髄反射的に Reducer のヒープメモリを増強すると却って傷が広がるので要注意。

事象

MapReduce は以下のようなイメージで動く。象本に載っているのと同じ図がインターネットに転がっていたので拝借。

f:id:garbagetown:20160311203803p:plain

問題が起こっているのは reduce task"Sort" phase のところ。

mapper が分割したデータのうち、自分が集計するものを集めてマージするわけだけど、mapper が分割したデータは上図のように全部同じ大きさではなくて、あるものは小さいし、あるものは大きい。

そんな状況において限りあるリソースを最大限に活用してできるだけ速くマージするために、小さいデータはメモリに載せて、大きいデータはディスクに吐く。

このうち、ディスクに吐いたデータは当然メモリを使わないので今回の問題には関係なくて、小さいデータが積もりに積もってヒープを食い尽くしてしまったという話。

以下、原因と対応。

原因

結論から先に書くと、CDH 5.1.2 (に同梱されている Apache Hadoop 2.3.0) のデフォルト設定値と実装バグが原因。

設定値

マージに使えるメモリ量 (memoryLimit) は、下記の通りデフォルトでコンテナが使えるメモリの 90% に設定される。

一方で、データをメモリに載せるかディスクに吐くかの閾値 (maxSingleShuffleLimit) は、下記の通りデフォルトで memoryLimit の 25% に設定される。

仮にコンテナのヒープメモリを 1GB に設定した場合、225MB (=1,000 * 0.9 * 0.25) 以下のデータはメモリに載せて、それより大きいとディスクに吐く。

これだけだと小さいデータをどんどん拾ってきた場合に memoryLimit に到達してしまうので、ここにも閾値 (mergeThreshold) が設けられていて、デフォルトで memoryLimit の 90% に設定される。

つまり、メモリでマージするデータ量が 810MB (=1,000 * 0.9 * 0.9) を超えるとディスクに書き出してメモリを解放する。これはスピルレコードとしてレポートに出力されて、チューニングの指標になる。

実装

牧歌的な逐次実行脳で考えると上記の設定で問題ないように思えるけど、現実は甘くないので mapper からデータを拾う処理はマルチスレッドで動いていて、スピルレコードを書き出している最中にもデータがどんどん飛んでくる。

このため、最後の砦としてメモリ使用状況をチェックする処理が入っているんだけど、残念ながらこれがバグっている。

具体的には以下の箇所で、

if (usedMemory > memoryLimit) {

現状のメモリ使用量だけではなく、これから扱おうとしているデータ量も考慮して

if (usedMemory + requestedSize > memoryLimit) {

と判定しなければならない。

これができていないので、例えば

  • コンテナのヒープメモリが 1GB
  • すでにマージ用メモリに 890MB 載っている
  • スピルレコードの書き出しは終わっていない

という状態で、mapper から 200MB のデータを拾ってきたとすると、上記チェック処理は

  • メモリ使用量は memoryLimit に到達していない
  • 200MB は maxSingleShuffleLimit より小さい

と判定してデータをメモリに載せようとするので、メモリ使用量は 1090MB (=890 + 200) となり、ヒープメモリを食い尽くして Reducer が死亡する。

対応

実装はまだ直っていない。2.8.0 で直るらしい。

自分で実装を直してビルドするような豪傑でない場合は設定値をいじって対応する。最新の Hadoop では memoryLimit のデフォルト値が 70% に変更されているので、これに倣えばよい。

2016/04/20 修正

CDH 5.1.2 では設定ファイルで memoryLimit のデフォルト値を 70% に設定していた。Mapper の数に対して Reducer が少な過ぎたためにスピルレコードの書き出しが間に合わなかったと考えて、Reducer 数を増強した。Reducer 数は Mapper の総出力ファイルサイズをブロックサイズで割って算出すればい。

まとめ

以上のとおり、処理タイミングに依存した問題だったため再現性が低くて苦戦したが、原因が分かってすっきりした。

それから、(たぶんヒープサイズの問題ではないとぼくが止めるのも聞かずに) 脊髄反射的にヒープメモリを増強したら、これまではディスクでマージしていたサイズのデータもメモリに載るようになり、却って再現性が高まってウケた。

当たり前だけど、問題は論理的に原因を切り分けて対処しましょうと再認識。システム開発にオカルトは存在しない。

参考

Hadoop 第3版

Hadoop 第3版

cygwin で sbt

職場のウインドーズに sbt が入っていなかったので入れた。

インストール

以下を読みながら tar を落として開いてパスを通した。

# yu-umezawa at 64PC0254 in ~ [12:23:51]
$ cd /usr/local

# yu-umezawa at 64PC0254 in /usr/local [12:23:55]
$ wget https://dl.bintray.com/sbt/native-packages/sbt/0.13.9/sbt-0.13.9.tgz
--2016-02-05 12:24:10--  https://dl.bintray.com/sbt/native-packages/sbt/0.13.9/sbt-0.13.9.tgz
dl.bintray.com (dl.bintray.com) をDNSに問いあわせています... 108.168.243.150, 75.126.118.188
dl.bintray.com (dl.bintray.com)|108.168.243.150|:443 に接続しています... 接続しました。
(snip)
2016-02-05 12:24:13 (7.40 MB/s) - `sbt-0.13.9.tgz' へ保存完了 [1049367/1049367]


# yu-umezawa at 64PC0254 in /usr/local [12:24:14]
$ tar zxvf sbt-0.13.9.tgz
sbt/
sbt/conf/
sbt/conf/sbtconfig.txt
sbt/conf/sbtopts
sbt/bin/
sbt/bin/sbt.bat
sbt/bin/sbt
sbt/bin/sbt-launch.jar
sbt/bin/sbt-launch-lib.bash

# yu-umezawa at 64PC0254 in /usr/local [12:24:23]
$ rm sbt-0.13.9.tgz

# yu-umezawa at 64PC0254 in /usr/local [12:24:36]
$ vi ~/.zshrc

# yu-umezawa at 64PC0254 in /usr/local [12:25:13]
$ grep -i sbt ~/.zshrc
export SBT_HOME=/usr/local/sbt
export PATH=$PATH:$SBT_HOME/bin

# yu-umezawa at 64PC0254 in /usr/local [12:25:20]
$ source ~/.zshrc

バージョン確認

バージョンを確認して終わりと思ったら意外とむずかしかったのでググったら特攻ブログがヒットして助かった。

# yu-umezawa at 64PC0254 in /usr/local [12:25:48]
$ sbt --version
[error] Not a valid command: version (similar: session)
[error] version
[error]        ^


# yu-umezawa at 64PC0254 in /usr/local [12:26:14]
$ sbt
[info] Set current project to local (in build file:/C:/gnupack_devel-13.04-2015.06.27/app/cygwin/local/)
> sbt-version
[info] 0.13.9
>

参考

#ScalaMatsuri 2016 に参加してきた

scalamatsuri.org

一日目

友人の結婚式に招待して頂いたので残念でしたが欠席。二次会はデリリウムカフェで十種類のベルギービールが飲み放題でした。

二日目

前日に痛飲したため午後から参加。参加したセッションは以下。二日目はアンカファレンスとのことで、もっとだらっとした雰囲気になるかと思いきや、予想以上にがっつり話が聴けて楽しかったです。

ScalaとSparkによる日本語テキストマイニング

以前にコップ本をくださったゴンザレスさんのセッション。Spark と Kuromoji による日本語テキストマイニングの手順を丁寧に解説されていて非常に分かり易かったです。

最後にぽろっと言っていた「"ヤバい" がいい意味にも使われるので機械学習がむずかしい」に笑いましたw

Typesafeの人にリアクティブについて聞こう

Typesafe の皆さんによるガチリアクティブトーク。

リアクティブやストリームという言葉がいろいろな意味で使われているので混乱しがちですが、 岡本さん さんが質問しながらご自身のスライドを表示してくださったので分かり易かったです。

DDD+CQRS+EventSourcing

恥ずかしながら CQRS について何も知らなかったので、あまり感想がない...加藤さんがツイートされていた pdf を読んでみます。

Scala 転職・年収

正直ちょっとエンジニア目線過ぎる内容だなあと思いましたが、オフレコで生々しい話が聴けました。

懇親会

おえさん たちのご好意で懇親会にもお邪魔させていただきました。

tabelog.com

Play Framework のドキュメント翻訳がずっと止まってしまっていることを Christopher Hunt に謝ったところ、笑顔で次に会うときに Play Framework T シャツをあげるよと言ってくれました。そのときまでにもっと英語を話せるようにならないと...

あと Typesafe のみなさんが Play Framework Japan ステッカーを喜んでくれたのがうれしかったです。

ちなみに きの子さん が翻訳をやってみたいと言ってくれたので、一旦ストップしてしまった反省を踏まえて、無理せず継続できる仕組みを考えつつ、もう一度がんばってみようと思います。

まとめ

最後に、Scala 祭り運営スタッフのみなさん、本当にお疲れさまでした。二日目しか参加できませんでしたが、国境を越えた交流を感じられるすばらしいイベントだったと思います。

また、当日お話をさせて頂いたみなさん、本当にありがとうございました。またよろしくお願いいたします :-)

cygwin で rails する

職場のウインドーズrails したいんだけどコマンドプロンプトが大嫌いなのでイバラの道とは知りつつ cygwinrails してみた。

なお、過去の経験上、生の cygwinrails どころか ruby を入れるだけで二人月くらい掛かるので、昨年からもともと ruby が入っている gnupack に oh-my-zsh を入れて使っている。

以下、作業ログ。いつか誰か (三ヶ月後の自分を含む) がググるかもしれないので、長いけどエラーログもすべて貼る。

gem

ruby は 2.2.2 が入っていた。意識低めなので今のところ rbenv は使わない。

gem が入っていなかったので apt-cyg でさくっとインストールする。

$ ruby -v
ruby 2.2.2p95 (2015-04-13 revision 50295) [i386-cygwin]

$ gem -v
zsh: command not found: gem

$ apt-cyg install rubygems
(snip)
Package ruby-rdoc installed
Package ca-certificates is already installed, skipping
Package cygwin is already installed, skipping
Package rubygems installed

$ gem -v
2.4.8

rails

どうせどこかで失敗するんだろうなと予感しつつ rails を入れたら、お馴染みの nokogiri でコケた。

$ gem install rails -v 4.2.2
(snip)
Fetching: nokogiri-1.6.7.2.gem (100%)
Building native extensions.  This could take a while...
ERROR:  Error installing rails:
        ERROR: Failed to build gem native extension.

    /usr/bin/ruby.exe -r ./siteconf20160121-1180-1s3cu4.rb extconf.rb
checking if the C compiler accepts ... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
        --with-opt-dir
        --without-opt-dir
        --with-opt-include
        --without-opt-include=${opt-dir}/include
        --with-opt-lib
        --without-opt-lib=${opt-dir}/lib
        --with-make-prog
        --without-make-prog
        --srcdir=.
        --curdir
        --ruby=/usr/bin/$(RUBY_BASE_NAME)
        --help
        --clean
/usr/share/ruby/2.2.0/mkmf.rb:456:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
        from /usr/share/ruby/2.2.0/mkmf.rb:571:in `block in try_compile'
        from /usr/share/ruby/2.2.0/mkmf.rb:522:in `with_werror'
        from /usr/share/ruby/2.2.0/mkmf.rb:571:in `try_compile'
        from extconf.rb:80:in `nokogiri_try_compile'
        from extconf.rb:87:in `block in add_cflags'
        from /usr/share/ruby/2.2.0/mkmf.rb:619:in `with_cflags'
        from extconf.rb:86:in `add_cflags'
        from extconf.rb:336:in `<main>'

extconf failed, exit code 1

Gem files will remain installed in /home/.gem/ruby/gems/nokogiri-1.6.7.2 for inspection.
Results logged to /home/.gem/ruby/extensions/x86-cygwin/nokogiri-1.6.7.2/gem_make.out

ざっと調べて libxml2, libxslt, libxml2-devel, libxslt-devel を入れてみても駄目。

$ apt-cyg install libxml2 libxslt libxml2-devel libxslt-devel
(snip)
Package libxml2-devel is already installed, skipping
Package libxslt is already installed, skipping
Package zlib-devel is already installed, skipping
Package libxslt-devel installed

$ gem install rails -v 4.2.2
(snip)
Building native extensions.  This could take a while...
ERROR:  Error installing rails:
        ERROR: Failed to build gem native extension.

    /usr/bin/ruby.exe -r ./siteconf20160121-4560-flmffc.rb extconf.rb
checking if the C compiler accepts ... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
        --with-opt-dir
        --without-opt-dir
        --with-opt-include
        --without-opt-include=${opt-dir}/include
        --with-opt-lib
        --without-opt-lib=${opt-dir}/lib
        --with-make-prog
        --without-make-prog
        --srcdir=.
        --curdir
        --ruby=/usr/bin/$(RUBY_BASE_NAME)
        --help
        --clean
/usr/share/ruby/2.2.0/mkmf.rb:456:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
        from /usr/share/ruby/2.2.0/mkmf.rb:571:in `block in try_compile'
        from /usr/share/ruby/2.2.0/mkmf.rb:522:in `with_werror'
        from /usr/share/ruby/2.2.0/mkmf.rb:571:in `try_compile'
        from extconf.rb:80:in `nokogiri_try_compile'
        from extconf.rb:87:in `block in add_cflags'
        from /usr/share/ruby/2.2.0/mkmf.rb:619:in `with_cflags'
        from extconf.rb:86:in `add_cflags'
        from extconf.rb:336:in `<main>'

extconf failed, exit code 1

Gem files will remain installed in /home/.gem/ruby/gems/nokogiri-1.6.7.2 for inspection.
Results logged to /home/.gem/ruby/extensions/x86-cygwin/nokogiri-1.6.7.2/gem_make.out

ログを確認すると /usr/lib/gcc/i686-pc-cygwin/4.9.2/../../../../i686-pc-cygwin/bin/ld: -lgmp が見つかりません とのことだったので、libgmp-devel を入れたら無事に rails が入った。

$ apt-cyg install libgmp-devel
(snip)
Package gmp installed
Package cygwin is already installed, skipping
Package libgmp-devel installed

$ gem install rails -v 4.2.2
(snip)
Done installing documentation for rack, concurrent-ruby, sprockets, nokogiri, loofah, rails-html-sanitizer, rails-deprecated_sanitizer, rails-dom-testing, rack-test, actionview, actionpack, sprockets-rails, thor, railties, bundler, arel, activemodel, activerecord, globalid, activejob, mime-types, mail, actionmailer, rails after 397 seconds
24 gems installed

が、パスが通っていなかったので .zshrc に home/bin を追加。

$ rails -v
zsh: command not found: rails

$ /home/bin/rails -v
Rails 4.2.2

$ vi ~/.zshrc
$ tail -1 ~/.zshrc
export PATH=$PATH:/home/bin

$ source ~/.zshrc
$ rails -v
Rails 4.2.2

sqlite3

雑に作った rails アプリケーションに bundle install したら今度は sqlite3 で失敗。

$ bundle install --without production
(snip)
Installing sqlite3 1.3.9 with native extensions

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /home/.gem/ruby/gems/sqlite3-1.3.9/ext/sqlite3
/usr/bin/ruby.exe -r ./siteconf20160121-2500-vm72n8.rb extconf.rb
checking for sqlite3.h... no
sqlite3.h is missing. Try 'port install sqlite3 +universal',
'yum install sqlite-devel' or 'apt-get install libsqlite3-dev'
and check your shared library search path (the
location where your sqlite3 shared library is located).
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
        --with-opt-dir
        --without-opt-dir
        --with-opt-include
        --without-opt-include=${opt-dir}/include
        --with-opt-lib
        --without-opt-lib=${opt-dir}/lib
        --with-make-prog
        --without-make-prog
        --srcdir=.
        --curdir
        --ruby=/usr/bin/$(RUBY_BASE_NAME)
        --with-sqlite3-dir
        --without-sqlite3-dir
        --with-sqlite3-include
        --without-sqlite3-include=${sqlite3-dir}/include
        --with-sqlite3-lib
        --without-sqlite3-lib=${sqlite3-dir}/lib
        --enable-local
        --disable-local

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /home/.gem/ruby/extensions/x86-cygwin/sqlite3-1.3.9/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /home/.gem/ruby/gems/sqlite3-1.3.9 for inspection.
Results logged to /home/.gem/ruby/extensions/x86-cygwin/sqlite3-1.3.9/gem_make.out

sqlite3 と libsqlite3-devel を入れたら動いた。

$ apt-cyg install sqlite3
(snip)
Package sqlite3-vfslog requires the following packages, installing:
cygwin libsqlite3_0
Package cygwin is already installed, skipping
Package libsqlite3_0 is already installed, skipping
Package sqlite3-vfslog installed
Package sqlite3 installed

$ apt-cyg install libsqlite3-devel
(snip)
Package libsqlite3-devel requires the following packages, installing:
libsqlite3_0 cygwin
Package libsqlite3_0 is already installed, skipping
Package cygwin is already installed, skipping
Package libsqlite3-devel installed

$ bundle install --without production
Fetching gem metadata from https://rubygems.org/..........
Fetching version metadata from https://rubygems.org/...
Fetching dependency metadata from https://rubygems.org/..
(snip)
Bundle complete! 17 Gemfile dependencies, 75 gems now installed.
Gems in the group production were not installed.
Use `bundle show [gemname]` to see where a bundled gem is installed.

以上。