2013年3月27日水曜日

GWT-Bootstrap: アイコンをFlexTable内で動的に生成する

前記事では、UiBinderで宣言しておいたDivタグに対して、動的にアイコンを埋め込む方法を紹介しました。今度はちょっと応用技です。
  • 動的に生成されるFlexTableの各行にアイコンを埋め込む
というのをお題にします。方法は以下の通り。
Element div = DOM.createDiv();
div.setClassName("icon-bookmark-empty");
fTable.setHTML(0, 0, div.toString());
上記のコードでは、div要素を動的に生成し、それをtoStringでHTMLとしてテーブルに埋め込む、、、という1行目と3行目がポイントです。

GWT-Bootstrap: アイコンを利用する

GWT-Bootstrapには、本家と同様にいくつかのアイコンが用意されています。この使い方は、以下の通り。
<i class="icon-asterisk"></i>
<div class="icon-asterisk"></div>
上記のように、UiBinderでiタグやdivタグにアイコンのclass指定をすることで、アイコンが埋め込まれます。spanタグでもいいでしょう。

ただ、アイコンを静的に埋め込んでおくのは芸がなく、やはり動的に埋め込みたいものです。その際は、空の要素のdivタグ等を用意して、それをJava側から制御すればOK。その記述方法は下記の通り。
@UiField
DivElement dd;

dd.setClassName("icon-angle-right");


2013年3月25日月曜日

DynamoDB:DynamoDBのプロビジョニングされたスループットを探ってみた

おちラボでは、昨年度からDynamoDBをバックエンドとするDBについて密かに?試作しているんですが、実はDynamoDB のキモとなる
プロビジョニングされたスループット
なるものについては、よくわからずに使っていました(つまり、そんなに本格的に使ってないということなんですけどね ^^; )。

で、最近、ネット界隈で、
DynamoDBにおけるスループット超過対策 〜 Fallback-Queueingパターン
なる記事が話題になっているようで、 DynamoDBの正体とその解決策に、なるほどーっと感心していたわけですが、、、

DynamoDBってそんなめんどくさいサービスなのか???
記事を読んでみて素朴な疑問が出てきたわけです。というか、1年間ちょこっと触ってみて個人的に感じたDynamoDBの欠点は、
  • テーブル毎に課金されるということはテーブルいっぱい作れない!!
ってことがまず1点。課金をケチろうと思ったら従来のRDBみたいな考え方ではアカンのですよね。で、今回の話題で発覚したのが、
  • リクエストスループットは、プロビジョニングされた容量を超えるとリクエストが失敗する
というさらなる欠点が、、、失敗したらどーなるの?データは反映されない?そんなのデータベースって使い物にならんだろう。と思うのは僕だけでしょうか?
で、その解決策として、上記のBLOGの解決策は秀作なんですが、これって元々のDynamoDBが奨励している使い方ではないですよね。いわゆる高等テクニックなわけで、ちょこっとプロトタイプ作ってみましたーみたいなレベルの我がラボのようなところではちょっと敷居が高すぎます。

例外処理で条件ワケするってのはどーも気持ち悪い
上記、BLOGを見ると「ProvisionedThroughputExceededException」というのが、プロビジョニングされた容量を超えた場合に発生するということがわかりました。(へぇ!へぇ!へぇ!へぇ!)
しかし、例外処理を条件分岐のように使うってのは、オブジェクト指向的に美しくないって習いませんでしたか?いや私も習ってませんが、どこかの本にそんなこと書いていた気がします。もっと、スマートなやり方ってないのかな?

getUnprocessedItemsメソッドというのがあるらしい!
ちょっといろいろぐぐってみると、getUnprocessedItemsというメソッドがあり、簡単にいうとBatchWriteItemのような処理で書き込みできなかったアイテムのリストを取り出すことができるということ。これを使えば、書き込みの再試行ができるというわけです!サンプルプログラムは下記のようになります。
do {
 batchWriteItemRequest.withRequestItems(requestItems);
 result = client.batchWriteItem(batchWriteItemRequest);
 requestItems = result.getUnprocessedItems();
} while (result.getUnprocessedItems().size() > 0);
ごらんのように、最初にrequestItemsを渡してバッチ実行したあと、getUnprocessedItemsメソッドでrequestItemsで取り残されたアイテムに更新し、もし取り残しがあれば再度バッチ実行するということです。この方法により、ループが回り続ける限り、登録は行われることになります。

ちょっと試してみた
getUnprocessedItemsメソッドで出力されるリストの中身を確認すれば、どんな感じに処理が失敗していくのかがわかります。空であれば、一発でバッチ登録は成功、そうでなければ失敗したということになります。条件として、
  • プロビジョニングスループットを1にしたテーブルを用意
  • batchWriteItemメソッドで、リミットの25件分のitemを一括登録する処理を20回繰り返す
というのを試してみました。挙動は予測するのはちょっと難しくて、最初の試行ではスムーズに登録完了しました。が、一度、中身を全て消して再度試行すると、途中のターンからリストに失敗したitemが残るようになりました。これはどういうことかというと、
  • 実際にリクエストしたスループット(Average Consumed Write Capactiy)の計算方法が単位時間によるもの
ということが想像出来ます、つまり単発的にデータを200件ほど追加するだけだと、プロビジョニングスループットを1にしていても問題なし。しかし、追加や削除などを繰り返すと、スループット平均値が上がってしまい、登録が失敗するということです。

上の図は、今回試した時のスループットのログです。赤線はプロビジョニングスループットの1です。青線の最大値は1.5です。
ちなみに、書き込みが失敗している場合、whileループが継続されてbatchwriteが行われるわけですが、ループを回るたびにitemのリストは1つずつ減って行きました。つまり、1item分しか処理されていないわけで、これってつまり、プロビジョニングスループットが1であるということなんですよね。

低レベルAPIでしかできないようだが、実は、、、、
getUnprocessedItemsメソッドを使えば、ループにより再処理ができ、漏れ無くデータを登録できることがわかりました。ただ、これが使えるのは、DynamoDBのSDKの低レベルAPIだけ。おちラボでは、高レベルAPIのmapperを使ってたんですが、これだとgetUnprocessedItemsメソッドが使えない模様です。もしかして、低レベルAPIで作り直し??
ちょっと気になって、高レベルAPIで同様の一括処理を試してみました。すると、データベースの中身を見てみましたが、時間はかかりますけどちゃんと入っているようです。どうやら高レベルAPIでは内部で同様の処理をしている模様(ソースを覗いたらはっきりするんでしょうけど)。つまり、、、再試行してくれててデータはちゃんとはいってるということ??

うーん、結局、気にしなくてもよかったのかなぁ。。。



2013年3月22日金曜日

2012年度大学院修了生を送り出して


2日連続で似たような話ですが、今日が大学院の修了式でラボからも1名が終了するので、、、、

修了生へ贈る言葉
研究科長の祝辞(3つのアドバイス)がいい話でしたのでそれをネタにして個人的なアドバイスを書いてみます。
(1)自分の専門にプライドを持て
院卒ならまあ当然ですよね。院卒というのは、ただたんに年を重ねて「院卒」という肩書きをもらうものではなく、研究活動で専門性や研究・開発力を高めたという証であるはず。修了後の仕事内容に関わらず、大学院で学んだことはいろいろな面で活かされるでしょう。それに気づかない人は残念な2年間を過ごしたということになるでしょうね。
(2)リーダーとして誠実な人間になれ
院卒=リーダーとは言い切れませんが、まあいずれは部下を持ったり、人を動かす立場になるでしょう。その時に求められるリーダーシップ、、、リーダーシップってなんだろう?いろいろな側面はあると思いますが、大切なのはリーダーたる魅力を持つことなんですよね。その1つに「誠実さ」という一見するとリーダーシップとは異なるようで重要な要素があるかと思います。リーダーになるというのは偉そうにすることではありません。責任をもって決断をし、集団を引っ張っていく必要があります。しかし、完璧なリーダーというのは存在しないわけで、何かミスやトラブルが起きた時にどうするか?その時、皆が支えてくれるリーダーであるかどうか?良い部下あっての良いリーダーであり、良いリーダーあっての良い部下なのです。
(3)幸せは勝ち取れ
「♪幸せは〜歩いてこない」ってことです。待っているだけでは何も始まらないし、進まない。幸せになりたい!のであれば、どうすればいいか?誰かが持ってきてくれるものではなく、まずは行動せよということですね。この話は実は奥が深いと思ってます。昨今の日本の産業の停滞感、、、今は冬の時代だがここを我慢すればまた春(バブル)がやってくる、、と思ってませんか?我慢する=待つのであれば、永遠に春は来ません。動く=変えていく必要があるのです。院卒の修了生はそういう人材になってほしいと思ってます。

以上、、、修了、おめでとうございます。

2013年3月21日木曜日

2012年度卒業生を送り出して


卒業おめでとうございます!今年は学部生11名、院生1名が巣立ちます。昨年度が少なかったせいか今年はいろんな意味で卒論指導に疲れました。残念ながら就職が決まっていない学生もいますが、いずれにしても卒業はゴールではありません。新しい人生の始まりです。

卒業生へ贈る言葉
今年も学科長の祝辞の内容(3つのアドバイス)をベースに書いてみようかと思いますが、共感すること多々あり。。。というか、今年のゼミ生の印象を一言で表現するとすれば、
みんなマイペースだったなぁ
という感じ。まあこれはいい意味であり、悪い意味でもあり。。。だからこそ、3つのアドバイスはしっくりきました。

(1)失敗を恐れずチャレンジする
失敗できるのは若者の特権、学生の特権です。ではこの4年間、あるいは卒論を振り返ってチャレンジしたことはあったでしょうか?仕事というのは時には、難しいこと、リスクの高いことをしなければいけない時もあります。マイペースでのらりくらりとできるものではないのです。20代の失敗は失敗じゃない、、、というのが私の持論です。いろいろなことにチャレンジしてください。

(2)危機管理をしっかり。想像力を持って。
仕事は一人ではできません。社会というのはたくさんの人が関わりあっています。そして皆の考えや価値観は十人十色です。その中で予期せぬことが出てくるはずです。他人に干渉されずマイペースに生きるというのは現実として難しいでしょう。
また、ゼミ指導では、「締切り間際に相談するな。事前にホウレンソウをしろ。締切当日にわかりませんでした、できませんでしたというのは認められないよ」ということを言ってきましたが、よい結果を出す、悪い結果をださないようにするにはどうすればいいか?ということを想像してほしいですね。

(3)目標をうまく設定する
仕事は成果が求められ、そしてそのために消費できるリソース(時間、お金)は無限ではありません。有限のリソースの中で目標を達成するためににどうすればよいか?ゼミのプログラミングの指導でよく言ってきたことですが、大きすぎる目標(課題)、曖昧な目標(課題)というのはなかなかそれに向かって動きにくいです。また、それがうまくいかない時、なぜうまくいかないのか? 目標向かって進めてないのか?の分析もしにくいです。長期的な目標を持つことはもちろん大切ですが、それに向かってどうすすんでいくかというサブゴール(目標、課題)をいかにうまく設定できるか?が重要です。ただ、サブゴールに目を奪われすぎて、長期的な大きな目標を見失うのも問題です。目標をうまく設定する、、、これは簡単なようで難しいですね。

以上、思いつくことを書いてみました。マイペースな皆さんに幸あれ!


2013年3月11日月曜日

GWT4NBはまだ生きているようです

おちラボでは、開発環境をNetbeansからEclipseへ移行しましたが、その理由は、GWTやGAEの対応がEclipseのほうが公式に対応しているからということであり、個人的にはNetbeansは好きだったので、今、どうなってるんだろう?と気になってました。
ふと、ググってみますと、GWT4NBプロジェクトはまだ生きているようですね。
gwt4nb(GitHub)
ごらんのように、GitHubにリポジトリを移動して現在もバージョンアップが進んでいるようです。最新バージョンでGWT2.5に対応してます。
 一方、GAEの対応状況は進んでないようです。もし、GWTには関心があるがGAEには興味が無いというのであれば、Netbeansを使うという選択肢はありだと思います。GWTはあくまでもクライアントサイドの技術ですし、GWTーRPCもただServletをラップしているだけですから、コンテナは選びませんしね。