balmysundaycandy-scala betaをリリースしました!

なんやかんやあって時間がかかってしまいましたが、ajn6で発表したツールが僕以外にも使ってもらえそうな仕組みにできたので、ひとまず公開します。
ただし、productionでのトランザクションはやっぱりサポートできていません。この辺りの実装具合は後で触れます。



概要から簡単に説明していこうかと思います。

balmysundaycandy-scalaは、scalaのREPL(インタプリター的なもの)を拡張してappengineのapiをたたけるようにしたリモートツールです。
scalaのインタプリターでappengineのサービス呼び出しを行うと、自動的に呼び出しがサーバー側に転送され、サービス呼び出しを実行し、インタプリターに実行結果が戻されます。

例えば、

balmysundaycandy-scala>val entity = new Entity("test")
entity: com.google.appengine.api.datastore.Entity = 
<Entity [test(no-id-yet)]:
>

balmysundaycandy-scala>val key = Datastore.put(entity)
key: com.google.appengine.api.datastore.Key = test(77001)

balmysundaycandy-scala>val list = Datastore.query(key).asList
list: java.util.List[com.google.appengine.api.datastore.Entity] = 
[<Entity [test(77001)]:
>
]

などのように、直接apiをたたくことができます。



興味のある方は、試す方が速いのでダウンロードしてみてください。ダウンロードはこちら。
http://balmysundaycandy.googlecode.com/files/balmysundaycandy-scala.zip



scalaは、2.7.7 finalでテストをしており、snow leoperdとwindows xpで動作確認しています。だめっぽかったら教えてください。また、ここから先のインストラクションはscalaがインストールしてあることが前提です。

ダウンロードしたら、インストール先の適当なディレクトリに解凍したbalmysundaycandy-scalaを配置して、そのディレクトリにBALMYSUNDAYCANDY_SCALA_HOMEを設定してください。

次に、balmysundaycandy-scalaを実行します。説明の都合上BALMYSUNDAYCANDY_SCALA_HOMEに移動してからでお願いします。

インタプリターが起動するので、おもむろに、:load remote.profile、とうちます。

marblejenka:bin marblejenka$ balmysundaycandy-scala
Welcome to balmysundaycandy-scala beta, Scala version 2.7.7.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_17).
Type in expressions to have them evaluated.
Type :help for more information.
balmysundaycandy-scala>:load remote.profile

すると、リモート呼び出しに必要な環境情報がセットアップされるので、あとはappengineにつなぎ放題です。ここでは、僕のアプリケーションにつなぎにいっています。billingしてないので、単に試してみたい目的でやっている人はこれを使ってもらってもかまいません。

やりたい放題のサンプルは、sampleディレクトリの下にあるので、見てみると良いかと思います。

remote.profileの実態はscalaのスクリプトで、Environmentの設定とapiのimportをやってくれます。scalaのスクリプトとして動作させているので、お好みに合わせて内容を書き換えてください。balmysundaycandy-scala-create-profileでプロファイルを作成することもできますが、scalaのスクリプトなので書き換えちゃった方が速いです。



また、自分のアプリケーションに接続させてメンテナンスなどの用途に使用したい方は、今のところhttpsをサポートしていないのでやらないのが懸命です。というか、まだ完成度が低いのでやらないでください。
どうしてもやりたい人、また、個人の環境で好き放題やりたい、そもそも会社のサービスじゃないのでhttpsである必要もない、というような方は、同梱してあるbalmysundaycandy-scala-remoteを別バージョンとしてデプロイし、プロファイルを作成のうえ使用することができます。
トランザクションを使用したい場合も、このプロジェクトでdevappserverをあげて、local.profileを使用するとトランザクションを使用することができます。



LogMode.verboseと打つと、このツールの真価を発揮します。



つくってみた感想。
・DSLではないにせよ、特定の目的に対するREPLという発想は割と有効なんじゃないかと思いました。あるインタプリターでは、どこかのデータベースのデータを簡単に使えるようになっているとか。割とありそうだし、素晴らしい発想というほどではないにせよ、インタプリターにDSLが同梱されているようなモデルはそれなりに価値があるのかも。
・scalaおもしろ。コンパイルの遅さ(コンパイルの遅さというよりはclassファイルを吐くまでの手間がjavaよりかかることによる遅さ)/eclipse pluginのできの悪さが足を引っ張る可能性はあるにしても、better javaって感じになってくれるんじゃないかなと。

という感じ。



これからのことですが、、

個人的には、実現したいことの一部しか実装できていないので、機能拡張はやっていく予定でいます。
具体的には、
トランザクションのサポート。未だに理由が特定できていないのですが、productionで取得したトランザクションがコミット/ロールバックできないバグがあります。
・リモートでのバッチ実行。関数全体をサーバー側で実行して、例えばデータのメンテナンスバッチなんかでのパフォーマンス向上を図りたいと思っています。これは、batch putなんかとは違って、インデックス異常を解消するためにget/putのひとまとまりを関数としてサーバー側に転送するイメージです。このへんは、あらかわ先生、ゆろよろ先生にいろいろ情報をもらっているので、実現できそうな気配はしています。
api wrapperの作成。さりげなくslim3が入っていたりするので、datastoreについてはslim3のDatastoreをlow level api wrapperとして使えば結構簡潔に記述できます。とはいえ、ほかのapiについては対話的に書くには記述が煩雑なところがあるので、scalaでのwrapperがあったら便利かなと思います。
・dslの作成。これは、アプリケーションをまたいだデータ移行・アプリケーションのバージョンアップに伴うデータ移行パターンの整理・クライアントを含むトランザクション制御パターン(いわゆるsmall tableパターン)の整理なんかがイメージとしてあります。
・Mastering the datastoreのチュートリアル作成。何せ対話的に見えるので、お勉強にはいいのではないかと。インデックス周りやどういう感じでデータが永続化されるのかはツールでは見えませんが、インストラクションと内部構造の説明がセットになってたら魅力的じゃないかなとか。
・slim3サポートの強化。今は、low level api wrapperとしてか使えないので、warディレクトリを指定するなどしてmete情報も使いつつ、というのを簡単にできるようにしたいです。今も、classpathを通せば使えることは使えるんですけどね。複数アプリケーション接続を将来イメージとして持っているので、アプリ固定のコンソール的な感じにしたくなかったのが今サポートできてない原因です。



機能拡張については、appengine ja hackathonなんかで興味のあるひとと一緒につくってみたいです。あらかわ先生はきっと協力してくれると思います。



夢が広がり気味ですね!この辺は、google codeのissueにまとめる予定です。
機能拡張は、scala2.8に合わせて作成したいと思っています。なので、リリース目標はscala2.8が出てちょっとしてから、という感じです。バグについては、何か経由で教えてもらえれば直します。twitterの@marblejenkaが一番確実です。

scala2.8ではREPLでのタブ補完が効くようになるので、ツール的には結構いけてる感満載になると思います。ただ、中の仕組みも変わっているはずなので、そこらへんの調査とかもやらないといけないです。
というか、いきなりツールをつくり始めたので、コップ本がまだ5章で止まってます。なんということでしょう!


なので、ペースはゆっくり目ですね。きっと。