RubyKaigi 2016 に行ってきました


RubyKaigi 2016

2016 09/08 〜 09/10 の三日間で、RubyKaigiが開催されたので、Ruby大好きなひとりとして参加してきました。

自分がRubyを触り始めたのはここ一年半くらいの話で、前回のRubyKaigiが開催された頃はまだRubyに本格的に染まる前だったので、自分がRubyistとして目覚めて初めてのRubyKaigiでした。

同じく大きなカンファレンスであるYAPCのお祭り感とは違って、ストイックにRubyの話題を中心にしたセッションが大半を占め、更にはCRubyやJRubyの実装にも深く立ち入った話が多く、単純にRubyを書く人だけではなくRubyを作っている人たちの目線を感じることも出来て、普段Rubyのコードを書いている自分から見て新鮮な刺激を感じました。(たまに全然Ruby関係ないよくわからないセッションもあって、それはそれで面白かったです)

今回のRubyKaigiのセッションの中で、ひときわ特徴的だったのは、コンカレンシーに関するセッションの数の多さと、CRubyに関するセッションの数の多さです。全40セッション中、6セッションがメインでコンカレンシーを、5セッションがCRuby(とそのエッセンス)を扱っていました。これは、ここ数年の関数型言語の考え方の流行だったり、マルチコアを活かしきるプログラミングをRuby3に期待している人が多いのだろうといった理由が感じられます。CRubyの話題の多さに関しては、Ruby3に向けてもっとコミッターに興味を持って欲しいという現コミッターたちの意識の表れではないかと思います。

半分は英語のセッションで、同時通訳も無かったので、必死に英語をリスニングして結構頭に効きました。面白いことに、日本語のセッションは英語の同時通訳があり、実に国際的なセッションなのだなということを感じました。

聴いたセッション

一日目

http://rubykaigi.org/2016/schedule/#sep08

  • Ruby3 Typing (Keynote)
  • dRuby in the last century
  • Who reordered my cord?!
  • A proposal of new concurrency model for Ruby 3
  • Isomorphic web programming in Ruby
  • Unifying Fixnum and Bignum into Integer
  • Scalable job queue system build with Docker

二日目

http://rubykaigi.org/2016/schedule/#sep09

  • Fearlessly Refactor Legacy Ruby (Keynote)
  • Writing a Gameboy Emulator in Ruby
  • How DSL work on Ruby
  • Learn Programming Essence from Ruby patches
  • Web Server Concurrency Architecture
  • Pwrake: Distributed Workflow Engine based on Rake
  • Modern Black Mages Fighting in the Real World
  • SciRuby Machine Learning Current Status and Future

三日目

http://rubykaigi.org/2016/schedule/#sep10

  • Ruby committer vs the World
  • Ruby3x3: How are we going to measure 3x?
  • High Tech Seat in mruby
  • It’s More Fun to Compute
  • Optimizing Ruby
  • Game Development + Ruby = Happiness
  • Dive into CRuby (Keynote)

特に凄かったやつ

3日かけて22ものセッションを聴きました。どのセッションも基本的に素晴らしいものでしたが、その中でも特にこれはヤバイなと思ったものを、いくつか感想として残しておきます。

Ruby3 Typing (Keynote)

Matzの基調講演で、Ruby3において型をどのようにして扱うかを、今現在のMatzの頭のなかにあるアイディアレベルで話してました。

Rubyには型がないから、最近新しく力を伸ばし始めた静的型付けの言語に比べて遅れているとよく言われる。しかし、技術というのはトレンドの間を振り子のように行ったり来たりするもので、いまは静的型付けの方に振り子が傾いているが、今後はどうなるかわからないので、Rubyは安易にその波に乗ることはできないと言っていました。これは、Matzのここ最近の講演で常に共通している意見で、YAPCの時N高特別授業の時も同じことを言っていました。

特に印象的だったのは、「絶対に型は書きたくない!」と「絶対にインターフェイスは書きたくない!」という2つの力強い宣言でした。

Rubyのダイナミックな言語仕様が尊重しているのはダックタイピングの概念で、静的型付けやインターフェイスではダックタイピングを壊してしまうため、安易に採用することはできないと、繰り返していました。継承の概念を大事にすると、たとえばIOやStringBufferの関係の様に、同じ挙動をするのに継承関係が無いオブジェクト同士のダックタイピングを阻害するということです。しかしその一方で、Goのように振る舞いを定義するインターフェイスに対してはかなり好意的な立場で、Goのインターフェイスは良くできていると強調していました。また、型推論というアイディアは素晴らしいが、それでも柔軟性を犠牲にするところが多く、何か新しい型の解決方法を考えつかないと、Ruby3に型の概念を入れることは難しく、現状はそのアイディアの実装がないので、Matz自身がプロトタイプを作ってコミュニティに問うていくしかないとのことでした。

dRuby in the last century

いきなりoso-matzとjushi-matzが出てきて、受けとか攻めとか言っててヤバイなこれって感じでした。

そしてdRubyの存在を初めて知りましたが、これは結構実用的で面白いのでは? と感じたので、家に帰っていろいろ触ってみようと思います。

A proposal of new concurrency model for Ruby 3

Guild、というRuby2との互換性を保ちつつ、Ruby3でコンカレンシーを実現するライブラリの提案でした。

アイディアはかなり面白く、Guildという1つのグループの中では今までどおりGVLが働くが、Guildグループは複数持つことができ、他のGuildとの間ではオブジェクトのやり取りに制限がつくという、ForkとThreadの中間(あるいは混ぜあわせ)のあるようなアイディアです。

1つのプロセスは必ず1つのGuildグループをもち、この最低1つは存在しているGuildが、今までのRuby2との互換のために使用される、すなわちRuby2は1つしかGuildグループが作れないGuildと同等ということです。

これがRuby3に採用されるとかなり面白いな、と思いました。

Isomorphic web programming in Ruby

Rubyでバックとフロントの両方のコードを書いてしまおうというアイソモーフィックライブラリ Menilite の紹介&ライブコーディング。

そもそもRubyでIsomorphicしようというスタイルが既にヤバくて面白いだけではなく、非常に完成度の高いライブコーディングのテクニックが披露され、発表そのものがショーのようで素晴らしかったです。

ライブコーディングはだいたいミスって、ミスるところまで含めてライブコーディングの楽しさというところがあるのですが、ゆうちゃんさんは

  • あらかじめ完成したコードをgitで管理しておいて、ライブコーディングの進みに合わせてコミットしておき、いざというときにリカバーする
    • Diffを見せながら解説を加えるので、実際にどういう変更が入ったのかがコミット単位でわかりやすい
  • TODOアプリを作りながら、実際にライブコーディングする内容をTODOする

といった、技術面でも演出面でも舌を巻く完成度で、絶対に真似しようと思いました。

Modern Black Mages Fighting in the Real World

Fluentd 0.14 を支える、黒魔術の話です。

トークが軽妙で面白いのに、扱っている内容が深刻すぎて引きつった笑いが出てしまう。みんな大好き黒魔術! という感じです。

同じ日の2つ前のセッションにHow DSL work on Ruby というセッションがありましたが、それと合わせてRubyの黒魔術の深い部分がよく伝わってくる、この2つのセッションを聞くだけで黒魔術師になれる最高のセッションでした。

Ruby3x3: How are we going to measure 3x?

Ruby3 を3倍の速さにする話ではなく、どうやって3倍の速さを計測するかという話でした。

ベンチマークに関する、体系だった知識を一度に頭に入れるには最適なセッションで、ベンチマーキングを正しく行うということの難しさとその原因をわかりやすく解説していました。

惜しむらくは、セッションが英語というだけで難しかったのですが、スライドが進むのが早く、頭の理解が追いつかないという点でした。このセッションのスライドは、ベンチマーキングを理解する上で非常に役にたつものになると思うので、どこかで公開されることを祈ってます。

It’s More Fun to Compute

Rubyで作曲。ヤバすぎ。国際会館のメインホールがダンスフロアと化した。最高。

Dive into CRuby

CRubyの世界への入り口、というにはちょっと専門的すぎて、さすがコミッターという格の違いを見せつけられたセッション。

主に2つの話題で、Rubyコミッタになるためにはと、CRubyにどうやって貢献するかという話。

新しい機能を提案するときには、ユースケースを正しく理解したうえで提案するべきであること、というのが非常に腹にストンと落ちてくる話で、普段の仕事にも活かせそうだと思いました。

心機能の提案時に、その機能をどのように使うか、そしてその機能の名前は本当に適切なのか、新機能という事象を研ぎ澄ますように精査して、本当に必要な使い方を見出していくという考え方はとても重要だと理解できました。

また、CRubyの世界を旅するときに、大事なことは現象を観測することだということも強調していました。様々なツールを使い、CRubyのメモリやコールスタックがどうなっているのか、解析ツールを使ってどこがボトルネックになっているのか、などを観測することで、Rubyの最適化やバグレポートに繋がると教えてくれました。

Drinkup by Misoca

二日目には、MisocaさんのDrinkupに参加させて頂きました。

途中、Misocaエンジニアに質問タイムがあったので、Rails4から5へのアップデートで苦労したところや、デプロイの戦略に関して質問してみたところ、丁寧に答えていただいてとても楽しかったです。

お料理とお酒、ごちそうさまでした。

RubyKaigi 2016 楽しかった

三日間の日程や、朝が早めであることから、体力的には結構辛かったですが、とても楽しめました。RubyKaigi最高です。

そういえばちなみに、Closingの時に「会社がRubyKaigiの費用出してくれた人ー?」っていう質問があって、ちらほら手が上がっているのを見て、「いま手を上げた人は、 #rubykaigi のハッシュと一緒に会社名をつぶやくと、リクルーティングの役に立つよ」と言っていたのがとてもおもしろかったので、来年は弊社の偉い人に「RubyKaigiのチケットと交通費ください! なんでもしますから!」ってお願いして、弊社の宣伝をドヤ顔でやってやりたいと思いました。

RubyKaigiのスタッフの方々、登壇者の方々、最高の三日間をありがとうございました。


カテゴリー: Ruby, プログラミング, ポエム | コメント / トラックバック: 0個

YAP(achimon)C::Asia Hachioji 2016 mid で、 Slack as a Game platform というLTしてきました


タイトルのとおりです

YAPC::Asiaが去年最終回を迎えて、いつかYAPCで登壇したいなと思っていた夢が終わってから1年。やっぱちーが開催されると聞いて、忙しい時期だけど絶対にLTくらいは出来ると思って応募して、無事採択されたので喋ってきました。

本家YAPC::Asiaに比べるととてもこぢんまりしていましたが、それでも集まった人たちは楽しそうにセッションをしたりそれを聞いていたりして、YAPCってこんな感じだよな、って雰囲気を感じられて楽しかったです。

自社のセミナールーム以外でやるカンファレンスで喋るのは初めてだったので緊張したけれど、ニコナレの録音を聞く限りではまあそこそこうまく喋れていたようなので安心した。

あとで自分のトークを見返せる(聞き返せる?)ニコナレ、素晴らしいサービスですね。

SlackGameのgemの0.2.0をリリースしました

YAPCの他のトラックを聞いている間に、0.2.0をパブリッシュしました。

半年くらい前に、お酒を飲みながらノリで書いたコードは酷いなぁと思いながら、とりあえず変なメソッド名や変数名を修正して、あとはReactionに対応して、リリースしました。

とりあえず、まだ問題点はあるので、近いうちに0.3.0にアップデートになると思います。


カテゴリー: ポエム | コメント / トラックバック: 0個

blink(1)を買ったので、雑にGemを作ってSlack監視botを作った


blink(1)

http://blink1.thingm.com/

プログラマブルなLED。同僚が社内の有志を募って共同購入して遊んでいたのを見て面白そうだったので、余ったものを売ってもらった。

たくさんの言語用のライブラリが用意されていて、大抵の人は好きな言語を使って開発できると思う。

用途

面白いなぁとおもって購入し、とりあえず一通りチカチカさせて遊んだけれど、特にこれといって用途が思いつかない。

同僚の人たちは、HTTPサーバーを立てて、リクエストに応じてLEDを光らせるAPIを社内公開するというよくわからない遊びに興じていた(しかも攻撃されてすごいことになっていた)が、とりあえず自分はSlackに新しいメッセージが投稿されたらチカチカ光るようにした。ついでに自分の名前がSlack上で呼ばれたら激しく光るようにして、誰かがリアクションをするとまた激しく光るようにした。

とはいえ、どちらかと言うとSlackだけではなく、HTTPサーバーを立ててリクエストで光るようにして、色んなサービスのリアルタイムAPIを繋げてピカピカ光らせるのが正しい使い方な気がする。

WindowsだとIFTTTと連携したりしていろいろ光らせられるらしいけど、Macにはそのソフトは用意されていない。

ならば自分で作るしか無いと思い、とりあえず予行練習ということで、blink(1)用のDSLを書いてみた。

Blinkman

blink(1)となんかしらのadapterを繋げて、DSLで光らせるgemを書いた。

https://github.com/kinoppyd/blinkman

とりあえず、今のところ存在しているadapterは、デフォルトのshellとSlack用のみ。暇があったらほかのも書こうかと思う。

https://github.com/kinoppyd/blinkman-slack

使い方は、Gemfileにblink-slackへの依存を書いて、簡単なDSLを書いて起動するだけ。

DSLの構成としては、blink blue の様に blink hoge で発光する色を指定し(現状で有効な色はred, green, blueのみ)、その後に 2.times で2回チカチカ、durin(250) で250 millisec で実行する、と指定する。

when_if のブロックは、どのメッセージを受信した時に発光するかを指定するブロックで、今回はSlackのRTMが返すJSONをパースしたオブジェクトがそのまま渡ってくる。そのうち、typeが’message’の場合、つまりSlackの自分が所属してるチャネルに何かしら新しいメッセージが投稿された場合に true を返して、発光するようにした。

今後

とりあえず、blinkmanは練習のつもりで書いたので、適当にメンテしていく。

ひとまずは、messageの中身がSlackのJSONそのままなので、IDとかの解釈がめんどくさい。それらをラップしたMessage Object を定義して、扱いやすくしていきたい。

blink(1)自体は、Raspberry Pi に繋いで、色んなサービスの通知に応じてチカチカさせるマシーンを作ろうと思っている。


カテゴリー: Ruby, プログラミング | コメント / トラックバック: 0個

S3クローンMinioを使って、自前MicroServices用データストレージを構築する


Minio

Minioという、S3のクローンサービスがある。Goで書かれたAWSのS3のオープンソースクローンで、API互換のあるすごいプロダクトだ。Minioの起動時のヘルプに書かれている説明が非常にわかりやすいので、そのまま引用する。

Minio – Cloud Storage Server for Micro Services.

S3は使いたいが、個人プロダクトだからそんな派手な利用をするわけではないし、そんなちまちましたことでS3の料金をシミュレーションしてわざわざ胃を傷めたくないので、何かしらいい感じのクローンが無いかと思って探していたところ、普通に[s3 互換][検索]でぐぐったら上の方にこのエントリが出てきたので、早速試してみた。

なお、Minioはサーバー版のDLページに移動すると書いてあるが、「Minio server is under active development. Do not deploy in production.」とのこと。確かに、コミット履歴を見てみると、そこそこの勢いで更新され続けている。自分は単なる自分用のしょうもないサービスのストレージに使いたかっただけなので問題ないが、素直にプロダクション環境に使いたいなら、S3を使ったほうが良さそう。あるいは、S3でCI回すのがコスト的にキツイ時の代替手段程度だろう。

起動

ダウンロードページにも書いてあるが、非常に簡単。

Goで書かれているので、単体のバイナリとして配布されているのが嬉しい。

ただ、上の方法だとhelpが表示されるだけなので、実際に起動するときは

の様に、serverコマンドとオブジェクトを保存するディレクトリを指定する必要がある。

起動すると、Minio内でAWSのaccess_key_idとsecret_access_keyとして扱える値が表示される。

素晴らしく簡単。

Webコンソール

Minioを起動すると、デフォルトでは9000ポートでサービスが起動し、同時に9001ポートでWebUIでMinioを操作できるコンソールが起動する。

ローカルで起動しているなら、http://localhost:9001にアクセスし、Minioの起動時に表示されたaccess_key_idとsecret_access_keyを入力すると、BucketやObjectを作って遊べるWebUIが提供される。

これを触っているだけでもそこそこおもしろいので、SDKからアクセスして挙動を試すために、いくつかBucketやObjectを登録しておくと良い。

Screenshot from 2016-03-07 02:41:51

 

とりあえず、テスト用にDownloadのフォルダにあったMemtestとUnetbootinを適当にぶん投げてみた。(どうして自分はUbuntuを使っているのに、rpmのファイルがDownloadに入っていたのだろう……?)

Rubyからのアクセス

素直に、Amazonが公式で用意している aws-sdk gem を使用する。

aws-sdk自体は、AWSの他のサービスのAPIも全て含んでいて、AWSを普通に使う分には申し訳ないのだが、今回のようにS3クローンのみを使うにはかなり巨大なコードベース、かつコードもあんまり読みやすくないので、正直なところ使いたくなかったが、他のS3に特化したgemではAWS4-HMAC-SHA256、通称V4と呼ばれる方式に対応しているものが見つけられず、かつMinioはこのV4を要求する。そのため、公式のSDKを使うのが最も手っ取り早いようである。もしかしたら、Minioの設定でV4をオフに出来るのかも知れないが、調べるのが面倒で調べていない。

なんらかの任意の方法でaws-sdkをインストールするが、とりあえずbundlerとpryを使って簡単にテストするには、次のようなコードが一番楽だと思う。

見づらい、が。

Aws::Credentialsクラスをわざわざ作っているが、どうせS3の機能しか使わないので、Aws::S3::Clientを作るときに直接指定しても良いかも知れない。

重要なのは、Aws::S3::Clientをnewするときに、endpointというオプションで ‘http://localhost:9000’ というアドレスを指定しているところで、これがAWSの繋ぎ先を変更し、ローカルのMiniに向けているところである。

また、おそらくURIを構築するときに何かあるのだろうが、force_path_styleオプションをtrueにしないと、Objectの取得が getaddrinfo: Name or service not known というエラーで終了してしまう。

そして作成されたクライアントに対してlist_bucketsのメッセージを送ると、先ほどWebUIで適当に作ったBucketsが返される。

list_objectでObjectの一覧の取得にも成功しているし、get_objectで、指定したローカルファイルにオブジェクトをコピーすることもできた。もちろん、MD5を取ってみたが、元のファイルと一致している。

すごいぞMinio

ざっと触ってみたが、個人ユースのS3を使っているプロダクトのバックエンドをまるっと置き換えても、そこそこ使えそうな雰囲気が素敵だ。

何より、最近はDockerを使ったり、作ってるものをなるべくポータブルにするように心がけていたりするので、何かしら永続的なストレージが必要だけど、S3ほど大げさなものは必要ないという場合にはとても強力な選択肢になりそうだ。

すべての機能は試していないが、Rubyのaws-sdkのgemでそこそこ動くので、他の言語に用意されているS3用のクライアントでも、比較的簡単に切り替えが出来るような気がする。これはかなり嬉しいことで、開発中は適当にMinioを使って、プロダクションにのせるときにS3に変更したい時も、ライブラリ構成を変更せずに、設定一つで切り替えられてしまうということだ。

とりあえず、目下は自分のしょうもないプロダクトのバックエンドに使ってみるのと、このブログもDocker上で動いているので、ファイルストレージをMinioに変更してスケールが出来るようにしてみたい。


カテゴリー: Linux, Ruby | コメント / トラックバック: 0個

ConoHaちゃんが好きすぎるので、WebAPIを叩くためのGemを(途中まで)作ってみた


この記事は、ConoHaちゃん Advent Calendar の22日目です

TL;DR

ConoHaちゃんが、普通にクラウドサービス的に使えて便利な上にマスコットは清楚かわいいしWebAPIも用意されていてプログラマフレンドリーだし、好きすぎるからAPI用のRubygemを途中まで作ったけどいろいろ大変だった話。

ConoHaちゃん

このはちゃんは、昔は一応VPSサービスと言っていましたが、リニューアル後はクラウドと名乗っています。フルSSDが使えて転送量は定額、そして一番小さなインスタンスだと国内で(たぶん)一番安い料金設定がステキです。

このはちゃんとの出会いは、丁度いまの会社に入った時に、同僚の人たちに「このサービスのキャラかわいいよ」と教えてもらったことに始まります。確かにキャラが可愛かったことと、サービスとしても気軽にサーバーを借りられて、しかも転送量が一定であること、さらに結構頻繁にイベントや勉強会をやっていて、そこでクーポンをばらまいてくれるというどの辺が清楚なのかわからないところが好きで、いまでは自分で何かするときにはとりあえずこのはちゃんのサーバーで検証してたりします。先日、別のAdvent Calendar に書いた「Deep learning でニコ生監視システム」にも、ConoHaちゃんのサーバーを使っています。

ちなみに、1年くらいはもらったクーポンで運用できてましたが、最近は普通に課金しまくってます。

ConoHaAPI

このはちゃんには、OpenStackに準拠した(らしい、実は私はよくわかってない)WebAPIが用意されていて、ほぼすべての操作をAPI経由で実行できます。できますが、APIの数がかなり多いのと、クエリをビルドするのが結構たいへんなので、これはライブラリ書くしかないなと思ってGemにしました。

conoha_api

Usage

問題点

conoha-apiは、以前に作ったGorakuと同様に、Octokitを参考に作られています。が、このはちゃんのAPIは、GithubやChinachuと違い、サービスごとにAPIのエンドポイントが変わります。たとえば、VMを操作するCompute Serviceと、アカウント情報を管理するAccount Service、アクセスの認証を得る Identity Serviceは、全部APIのホストが違います。ただパスが違うだけだったら良いんですが、普通にホスト名レベルで違います。最初は面倒だな程度に思っていましたが、実装を進めていくうちにいろんな問題にぶち当たりました。

ConohaApi::Clientのモジュールたち

ConohaAPIへのアクセスは、ConohaApi::Connectionモジュールに書かれたrequestメソッドから、Sawyerのラッパーを経由して行われます。そして各APIのエンドポイントは、ConohaApi::Clientクラスの名前空間の下にある、各サービス名に対応したモジュールに定義されています。たとえば、Computeサービスであれば、ConohaApi::Client::Computeモジュールにエンドポイントとメソッドとクエリが記述されています。

ここで問題になるのは、各モジュールでアクセスするホストが違うということです。OctokitやGorakuであれば、ConnectionモジュールをClientクラスにincludeし、Connectionクラスに定義されたget, put, post, patch, delete メソッドを呼び出すことで単一のエンドポイントに統一的にAPIにアクセス出来るのですが、conoha-apiの場合は、APIの定義されたモジュールごとに、ホストを切り替えなくてはいけません。

とりあえず、まずは各サービスのモジュールに、エンドポイントを定義して、呼びだされたモジュールごとにホストを切り替えたSawyerオブジェクト(agentという名前で定義して、requestの中から呼び出されます)の向け先を変えようと思っていました。ですが、ある程度実装を進めたときに、問題にぶち当たりました。

  1. Identity Service でアクセストークンを取得するときに、各サービスのエンドポイントが提示される
  2. ライブラリとしての使い勝手を考えた時、Identity Serviceへのアクセスは暗黙的に行われるべき

1つ目の問題点は、各モジュールにホストをハードコートできないということです。Identity Service にアクセスした時に取得する情報こそ真に信じるべき情報であって、エンドポイントの情報はハードコートされるべきではないからです。これに関しては、Identity Service にアクセスした時に、各エンドポイントの情報を保持することで対応は出来ました。Clientクラスが持っているクラス変数に、各モジュールの名前をキーにしたハッシュマップを用意し、その中にIdentity Service にアクセスした時の情報を保持しておきます。そして、各サービスのモジュールからメソッドをコールした時、Clientクラスはそのメソッドをスタックコールから確認し、そのモジュール名に対応したエンドポイントをクラス変数から引くようにしました。

更に大きな問題は、2つ目の問題でした。例えば、conoha-apiをrequireして、VMを立ち上げるためにComputeサービスにアクセスするために、わざわざClientオブジェクトを作成して、authを行う、という2ステップは行いたくありません。普通は、Clientオブジェクトを作成して、Computeサービスのメソッドをそのまま呼び出します。そうしたとき、Computeサービスが利用しているConnectionモジュールのAgentは、リクエストがあったときにまず認証情報があるかを内部的に確認します。そして、ない場合はIdentity Serviceにアクセスして、トークンを取得し、そして何事もなかったかのようにCompute Service のメソッドを呼び出します。こうすると、ユーザーが明示的にauth処理を行うこと無くライブラリを使えます。

ここで問題になるのは、実際にAPIを呼び出しているのはComputeモジュールなのに、内部で必要な通信はIdentity Serviceということです。ということは、1つ目の問題を解決した「呼び出し元のモジュールによってホストを変える」作戦だと、微妙にうまく行かなくなります。Connection#requestメソッドが複数回コールされた時、微妙に整合性がとれなくなります。

最初は、Connection#requestがコールされた時に、現在のagentをtmp変数に保持して、新しくagentを取得し、最終的にtmpに戻すという方法をとりました。しかし、これではrequestの中で使用されるagentメソッド自体に、自分がどこに接続されているかの情報を渡す必要があり、agentを毎回新しく作成しなさなくてはならないという、やや微妙な実装になりました。インスタンス変数自体にその情報を持っても良いのですが、少なくとも自分が書いたコードでは、なんだか複雑な見た目になってイマイチだと感じました。

そこで、Connectionクラスのインスタンス変数に、次に繋ぎたいエンドポイントをスタックとして所持することによって、この問題はひとまず回避しました。requestがコールされた時、スタックトレースからServiceのつなぎ先を取得しスタックに積み、agentメソッドがこのスタックを参照してSawyerオブジェクトを切り替えることで、コネクションのプーリングが可能になりました。スタックにすることによって、agentもconnectionも複雑な処理や見た目を持つこと無く、比較的わかりやすく書けたと思います。

もちろん、これはベストプラクティスとは思えないので、今後改良の余地はありますが、ひとまずこのように対応しました。

最大の問題点

Connectionモジュールの問題を解決すると、今度はまた別の問題が出てきました。ConoHaAPIは、数が多すぎることです……

数字の問題

ConoHaAPIは、かなりの数があります。Connectionの問題を解決したら、あとはAPIの仕様に沿って機械的にガーッとエンドポイントを定義していくだけなのですが、それでも大量のリクエストJSONの作成や、例外処理、デフォルト挙動の定義など、かなり時間のかかる作業です。

そのため、一旦公開するバージョンはv0.1.0として、Identity Service と Compute Serviceの一部を実現した形になりました。理由は、Identity Service と Compute Serviceさえ実現できれば、最低限のVMの操作を行えるからです。これ以上の各サービスは、順次時間と必要を見て実装していこうと思います。

お金の問題

ライブラリを作った以上、テストをしないわけにはいきません。

が、このはちゃんがいくらリーズナブルとはいえ、VMを落としたり立ち上げたりしてたら、まあそこそこのお金になることは想像できます。今のところ、かかっているお金は数十円ですが、これから先各サービスを実装していくうえで、金銭的な負担はまあまあのものになりそうな気がしています。

これに関しては、モチベーションだけではなく、財布的な意味でも辛いので、ConoHaAPIのサンドボックス環境ができるか、あるいは勉強会でクーポンをもらうまでは、あまり積極的に開発に臨めないかも知れません。

今後

とりあえず、他のAdvent Calendar のネタにした、Deep Learning でニコ生を完全監視システムを、API経由でぱぱっと立ち上げられるくらいには、ライブラリと周辺ツールを整備させていきたいと思います。

あと、すごくこのはちゃんのカレンダー欲しいです。今年の分は勉強会に行ったらもらえてすごくハッピーだったんだけど、リニューアル後はなんかあまり勉強会が開かれて無くて、このはちゃんと触れ合う機械が少なくて正直しょんぼりしています。


カテゴリー: Ruby, プログラミング, ポエム | コメント / トラックバック: 0個