ラベル GAE/J の投稿を表示しています。 すべての投稿を表示
ラベル GAE/J の投稿を表示しています。 すべての投稿を表示

2014年9月30日火曜日

#f1yosou を今シーズン限りでやめることにしました

公式アカウントから既におしらせした通り、これまで約4年半に渡って開催してきた #f1yosou ですが、今シーズンの終了を持って開催を終了することとしました。みなさん気を遣ってくださって、理由は特に聞かずに受け入れてくださっている方がほとんどですが、決定に至った理由を書いておきますね。

理由を一言で言うなれば「一定の役割を果たした」という感じでしょうか。当初の目的だった、ツイッターでゆるい感じの予想大会をして、それでF1好きの方々でわいわい楽しめたらいいね、という目的は果たせたかなと思います。

当初はサイトもなかったので、有志でお題を決め、予想を管理して、的中者の発表をしていました。人数も少なかったので、フォロワーさんの間でわいわいやりながら、特に強制することもなくおめツイートもしていましたね。そのうち管理が楽になるように私がサイトを作りました。私の技術不足(ウェブ周りの技術者じゃないのです)もあり、結構な時間を費やしましたが、参加していたみなさんからの暖かい言葉に助けられ、なんとか使える程度のサイトを作ることはできたのかなと思っています。

サイトが出来たことで、手作業に比べてはるかに楽になりましたし、F1の話題、しかも予想のお題が上位とは限らなかったので普段注目しない順位のドライバーの話題に一喜一憂できる楽しさがあったので、もっと多くの方と楽しめるように宣伝もし、おかげさまで2013年には最大51名もの参加者を集めることができるようになりました。主に私の技術的興味の側面もありましたが、サイトのリニューアルなんかも行ってきました。途中でインフラとして使っている Google App Engine の課金方法が変更され、それまでの方法ではすぐにサイトが使えなくなったりする苦労もありました。以降施したさまざまな改善により、最近はサイトが使えなくなるようなことはおきないようになりました。いやぁ、Datastore Read Operations の制限は厳しかったっすよ Google 先生。。

そんな苦労もありましたが、でも多くの方、特に初期のころから参加してくださってるみなさんは、ツイートの自動検出が難しいこと(投票のフォーマットは決めていないので)や、課金されないように運営することが大変なこと、などを理解してくださっていたので、いろいろ対策した後の効果の検証を助けてくださったり、何よりねぎらいの言葉をかけてくださったのが非常にうれしく、運営のモチベーションになっていました。

***

しかし、人数が増えたことだけが問題とは思いませんが、運営を続けるにつれ初期に比べて参加者のみなさん同士の新たなつながりは少なくなったように感じていました。的中者におめでとうのツイートをするのが唯一の賞品なわけですが、それを行わない方も多くなったように思います。もともとおめツイートをすることによって、これまでフォローしていなかった方と新たにつながったりできるといいよね、という考えで参加者を広く募ってきていたので、それが行われないとなると続ける意義がどれだけあるのかがわからなくなってきました。また、おめツイートをしても1ターン(?)で会話が終わることもほとんどで、なかなか新たなつながりには結びつかなくなりましたね。

さらに、最近は運営に対する批判もいくつか頂戴しました。上記のように、「ツイッターでゆるく予想を楽しむ」がコンセプトだったので、予想のツイートには特にフォーマットを定めておらず、そのために検出漏れ、検出間違い等はどうしても避けられませんでした。そのため「予想がおかしいです、直してください」というお知らせはよく受け取りましたが、多くのケースはドライバーの名前があまり見ないカタカナ綴りやあだ名になっているか、お題の答えになっていないケース(たとえば10位のドライバーを予想してください、というお題で、「10位は可夢偉」ではなく「可夢偉は10位」とツイート(お題の抽出精度を高めるために助詞の前後の関係とかも見てるのです))だったりすることが多かったです。その都度ある程度対応していますが、参加者全員の名前の読み方を統一することは不可能ですし、一部を調整すると他に検出漏れが出るなどの問題もあり、残念ながら手作業は欠かせない状況です。ですが私はもちろんこのサイト管理で食い扶持を得ているわけではないためサイトに張り付いて管理することはできず、どうしても対応は遅れがちになります。その状況で「まだ直ってないんですが」というツイートを何度かもらうのはさすがに滅入りました。それ以外は主に私の管理者としての問題に起因するのでしょうが、他にもいくつか批判を頂戴しました。

***

ですが、これらはある意味不特定多数の参加者を募っている時点である程度しかたのないことなんだと思います。サイトの運営で利益を上げているわけではないのでそれらの批判には腹も立ちますが媚びへつらう必要もないわけで受け流せばよいわけです。それよりも直接の原因となったのは、むしろ「孤独感」のほうかも知れません。

以前は何かサイトを改良したりすると参加者のみなさんからすぐに感想をもらえましたし、こんなことやってるよというツイートに誘われて今度参加してみますという会話がTL上にあったり、「Statsのページはまだかな(チラッ」のようにさりげなく期待の声があがっていたり。 もともとは予想1つだったのを2つを予想するようになったこと。ポイントシステムを採用したこと。これらもすべて私ではなく参加者のみなさんで決定したことでした。私やサイト、公式アカウントが何かするのではなく、みんなで決めていた、その感覚が楽しかったのかも知れません。最近参加された方はもちろんご存知ないと思いますが、サイトや公式アカウントのロゴも私が作ったのではありません。

それに比べると今は「管理者」としての立場が強すぎるのか、私自身もひとりで黙々とミスなく作業するのが当たり前という感覚ですし、参加者のみなさんから頂戴する批判からもかなりのみなさんがそのような感覚でいるのだと思えます。それは果たして #f1yosou が求めてきた姿なのでしょうか。これ以上運営していて何か意味はあるのでしょうか。

いろいろな変化があるとは言え、 #f1yosou をはじめたころに参加していたメンバーの大半が参加していないかまたはほとんどツイートしなくなってしまっています。シーズン末の結果発表にわざわざ「皆勤賞」「準皆勤賞」を設定しているのは、ずっと参加して盛り上げてくださっているみなさんに少しでもお礼・お祝いをしたいという気持ちで設定していますが、逆にほとんどツイートしていないのに #f1yosou だけ参加してくださってる方もおられ、そのような方にはむしろ余計な義務感を与えてしまっているのかもとさえ思います。もともとの「ゆるく予想して楽しもう」のコンセプトからは完全に離れてしまったと感じています。

***

このような考えに至り、そろそろ #f1yosou は幕引きの時期を迎えたのだろうと判断しました。公式アカウントとしては特に感情抜きで作業するようにしていますが、やはり日本GPは特別なものなので、発表は日本GPのころにしようと決めていました。参加者のみなさまには突然のお知らせとなって恐縮ですが、決めたのはもっと前になります。

もちろん、ツイッターのハッシュタグの性質上、この #f1yosou というタグになんら縛りがあるわけではないので、来年以降これをつかって予想する方々がおられても楽しいですし、どこかで似たようなイベントを起こす方がおられてもいいですね。私もどこかで参加するかも知れません。

以上、長文失礼いたしました。残り5戦となりましたが、参加者のみなさまと #f1yosou を楽しめるよう努力しますので、最後までお付き合いいただけるとうれしいです。公式アカウント、サイトとも今年いっぱいは維持する予定です。

2014年9月30日
@f1yosou と中の人 @Sdk0815

2013年4月29日月曜日

Eclipse のプロジェクトを IntelliJ IDEA に

ちょっと Heroku の話はお休みして。#f1yosou のサイトはとうとう GAE/J の無料分では Stats が計算できなくなり、あえなく Stats を閉鎖する運びとなりました。で、この際裏で進めていたサイト全体のリニューアルを先にしてしまおうかと思ったのです。なぜなら新しいデザインのほうはまだ Stats ができてなくて時間がかかるなと思っていたんですが、現行のほうも Stats が使えないならもう移行してしまってもいいわけですね。

とはいえまだ公開できるレベルではないのでもう少し実装・テストをする必要があります。なのでこの際現状は Eclipse で開発しているのですが、IntelliJ IDEA を使ってみようと思いました。Java 部分はそれほど大差ないかと思うのですが、Velocity とかこれまではほぼ自前/手書きだったのが便利になるのではという期待もこめて。


ソースコードは subversion にチェックインされているので現状 Eclipse にあるコードはすべてチェックインしておきます。そこからチェックアウトする流れで。 IntelliJ IDEA から VCS > Checkout from Version Control > Subversion を選びます。すると右のようなダイアログがでるので、リポジトリの情報を入力して選択します。その後どこに展開するか場所をしていします。


場所を指定すると次は右のようなダイアログが出るので、私は gae というフォルダ以下に gae 関連のプロジェクトを全部まとめておきたいので、真ん中のやつを選びました。これで gae というフォルダ以下に f1yosou というフォルダができて、そのファイルが中にチェックアウトされます。

するとどうでしょう。
お、Web プロジェクトで、GAE とさらに GWT も使ってることを検出してくれました。Configure を・・・

と思ってこのキャプチャをとっていたらこのポップアップは消えてしまいました!w でもしたの Event Log をクリックしたら同じメッセージとリンクがでていました。ナイスw
Configure をクリックするとこんなダイアログがでるので、OK。
すると File > Project Structure を表示して Facets を見ると、
のように定義されています。あとはここに SDK へのパスを入れたりすればよい。

・・・と思ったんですが、いろいろ問題が。そもそも Dev Server が起動しない(ブランクになる)とか。クラスパス関連がごしゃごしゃになってたりとか。そこでいろいろ苦労しながらなんとかできそうな状態に持っていったやり方を以下に書きます。

まずは新規に GAE/J + GWT のプロジェクトを作成します。File > New Project で Java Module を選択して Next。これで JDO を使う場合はその選択も忘れずに。これで空のプロジェクトができます。空ですがいろいろ設定されているのが大事。

Eclipse でプロジェクトを作った場合は恐らく web ディレクトリではなく war になっていると思うので、ここで web ディレクトリを war に Rename します。web の上で右クリック、Refactor > Rename で war にしましょう。この rename がなぜか反映されてないところがあるのでそこを修正します。プロジェクトを右クリックして Open Module Settings を開くと上にあるようなダイアログが開くので、Facets の Web を選んで、Web Resource Directory 名を変更します。

さていよいよもとのコードを移行します。VCS > Checkout from Version Control > Subversion で上記の作業をします。そのときのチェックアウト先を今作ったプロジェクトそのものにします(つまり上書きします)。そして VCS > Enable Version Control で Subversion を選びます。私の場合 jdoconfig.xml と appengine-web.xml、web.xml が青くなりました。つまりチェックインされているものが変更されているということですね。これらの変更を Revert しましょう。右クリックで Subversion > Revert で戻せます。あと不要な index.jsp も消します。

この状態だとライブラリはパスが通ってない状態なので、WEB-INF/lib に何か入れていた場合はこれらを追加しなければいけません。普通の Java のときと同様ですが右クリックして Add as Library で追加します。また Open Module Settings をして Artifacts の WEB-INF/lib のところに追加するのも忘れずに。

この状態で Run/Debug で AppEngine Dev サーバーを起動したところようやく起動できました。・・・できたんですけどブラウザには悲しいページが。

まだだ!くじけるな!

この話は(たぶん)IntelliJ IDEA 云々ではないようです。既に問題になっていたようで。なので解決方法は Run > Edit Configuration から開くダイアログの VM options に-XX:-UseSplitVerifier をつけるだけ。そしてサーバーを再起動すると・・・
やっとキター!(表示が変なのはデータがまだないからです。)

この勢いで GWT の起動構成も確認します。自分のモジュールの .gwt.xml を右クリックして Run/Debug 。VM Options が必要な場合は上と同様に入れます。そして起動、おりゃーっ!
orz

まあいろいろ起きるもんですね・・・。生みの苦しみかこれは。とはいえこれは簡単に直って、また起動構成に戻り、Server を Default から AppEngine Dev に切り替えて起動しなおすだけでした。ふー。

さあ後は deploy だな! Tools > Upload AppEngine Application を選ぶだけ!
java.lang.RuntimeException: The application contains Java 7 classes, but the --use_java7 flag has not been set.
Unable to update app: The application contains Java 7 classes, but the --use_java7 flag has not been set.
いじめか orz
きっと Java6 にすれば治るんでしょう。GAE って確かまだ Java7 は正式サポートじゃなかったような気がするし。いやもう眠いから調べないですけど。切り替え!もう一度 Upload!

で、できた・・・。

これで恐らく開発できる状態にまではたどり着けた、と思うのですが。しばらく使ってみて今後どうするか考えます。ちなみにこのやり方が正しいのかベストなのか等全く見当もつかないので、もし試す場合は自己責任でお願いします。

2013年3月22日金曜日

GAE/J + JDO で Single Property Index を作らせない

表題のとおりですがようやくたどり着いたのでメモ。

サイト自体にも書いていますが、#f1yosou Google App Engine/Java (以下 GAE/J)を使っています。もともと3年前(もう3年になりますか・・・)にはじめたときには結構余裕だったのですが、Googleさんの緩やかな締め付けwで無料での利用部分がどんどん制限されてきて、最初のころにはタコなコードを書いていても余裕があったのですが、最近はかなり厳しくなってきています。これまでもそれなりに使用量を抑制しつつなんとかごまかしてきました。

そんな最近の #f1yosou サイトのもっとも厳しい項目は、Datastore Write Operations の項目です。これは文字通り Entity を Datastore に書き込むと消費するやつですね。これが特に #f1yosou タグのついたツイートを解析して結果を書き込む処理を経るとかなり消費されます。処理としては
  • 該当するツイートの保存
  • 同一の予想をしたツイートのカウントを行い、その結果を保存
ということをしていますが、どうも後者の処理がかなりの書き込みを生じているようです。そもそもこの Datastore Write とは Entity を1つ書き込むと1回なのか?というところから調べ始めたところ、以下の記事がよくまとまっておりました。
EntityのPropetryの構成よって、Datastore writeの数は変わる!
なるほど。そもそもプロパティの数によって増えるのもあるんですがそれは実際に値をしまってるので仕方ないとして、各プロパティについて勝手に自動的に作成される Index の書き込みのほうが問題ですね。そもそも使ってないのに昇順・降順で2つ作られてるみたいですし。これを削減できればだいぶ効きそうです。ただし
Single Property Indexを作らないとComposite Indexも作成されない?
という考慮点もあるみたいなのでなんでもかんでも削れるわけではないようです。

と、ここまできて JDO ではどうやって指定するんだろう・・・と思って調べてもなかなかでてきません。いろいろググっていたらようやく Entity#setUnindexedProperty() なるものがでてきました。しかしこれも Low Level API。。。

まあそれでもいいか、と思ってやり方を探っていたらとうとう発見しました。まんまの質問がありましたw なぜこれに最初に行き当たらなかったのか不思議なぐらいそのままです。要するに
@Extension(vendorName = "datanucleus", key = "gae.unindexed", value="true")
を索引がいらないプロパティにつけるだけです。あら簡単。

早速実験してみます。1回処理すると以下のようになる Entity を用意しました。
 このクラス定義のところにある correct というプロパティに Index を作らないようにします。
 @Persistent
 @Extension(vendorName = "datanucleus", key = "gae.unindexed", value="true")
 private Boolean correct;
とすると、
のように2減りました。この2というのが昇順と降順で1つずつの結果のようです。
#上では赤丸がついている Entity にのみ処理をしました。

これで削減できるかな?

2013年1月14日月曜日

GAE/J でセッションの clean up

#f1yosou では一応セッションを使ってログインできるようになっています。個人の成績等が少し見れるようになっているのですがこちらの機能はほぼ使われてなくて、次のレースのお題を投票する際に使ってるのがほとんどでした。しかし GAE/J ではそのセッションのデータは Datastore に保存されているようなのですが、それがずっと残り続けてそれなりにサイズを圧迫すると。 #f1yosou では 14,000 ものセッションが残っておりました・・・。

なのでそれをクリーンしましょう。そのためのサーブレットが既に組み込まれているのでそれを使います。web.xml に以下の定義を追加します。

 <!-- session cleanup servlet -->
 <servlet>
     <servlet-name>_ah_sessioncleanup</servlet-name>
     <servlet-class>com.google.apphosting.utils.servlet.SessionCleanupServlet</servlet-class>
 </servlet>
 <servlet-mapping>
     <servlet-name>_ah_sessioncleanup</servlet-name>
     <url-pattern>/_ah/sessioncleanup</url-pattern>
 </servlet-mapping>
 <security-constraint>
     <web-resource-collection>
         <web-resource-name>session-cleanup</web-resource-name>
         <url-pattern>/_ah/sessioncleanup</url-pattern>
     </web-resource-collection>
     <auth-constraint>
         <role-name>admin</role-name>
     </auth-constraint>
 </security-constraint>

これを cron.xml 等で定期的に叩くことによってセッションのデータを少なく保てるようです。既に多数残っている今回のケースではその URL を何度も直接叩いて減らしました。その際 Datastore Writer 等が増えるので Quota に余裕がある時にどうぞ。

2013年1月3日木曜日

#f1yosou : HRD への移行

というわけで、HRD への移行を行ってみます。基本はガイドに従えばいいはず・・・。

TaskStatusRemarks
Duplicating Your ApplicationDone
Deploying Your New HRD ApplicationDone
Using the Migration ToolDone結構待ちます。

あれ、結構簡単でした?w

しかし実際は index の定義をちゃんと書いてるわけではない(Eclipse 上で実行していると自然と生成される定義を使っていた)ので、最初に新しいアプリケーションのほうに deploy したら索引が全くない状態になってしまいました。なので開発環境で適当に実行して生成された定義を使ってもう一度 deploy。今度はうまくいきました。

果たして migration した元のアプリケーションは消してよいのか。消さないと10個までというアプリケーション数の制限を圧迫するんだけど・・・。

同様にチェックしたDMログ(仮)は実はバグがあってだいぶ前から動いてなかったっぽい。けど何も言われてないってことはそろそろ消してもいいかな?政治家的にいえば「一定の役割は果たした」のでw

#f1yosou : 現状の説明

みなさんご存知の通り #f1yosou の中の人をやっているわけですが、今年もやるためには以前ツイートしたように、
といった作業が必要になります。作業を分類すると

必須の作業
  • HRD 移行
  • Twitter API V1.1 対応
ほぼ必須の作業
  •  公式アカウントによる参加者のフォロー&TL読み込み(Twitter API V1.1でリスト関連の API が変更になったため、どのみち何らかの作業が必要なため)
できればやりたい作業
  • DMによるお題投票
  • ログインシステム廃止
といった感じです。

このうち Twitter API V1.1 対応については Twitter4J V3.0.3 への更新が完了したので基本問題ないはずです。なので残る作業は HRD 移行とフォロー&TL読み込みです。

ちなみにHRDなんじゃそれと言う方も多いと思うので一応説明しておくと、#f1yosou のサイトは Google App Engine for Java といういわゆる PaaS サービス(の無料部分を!)利用しています。しかし #f1yosou サイトを立ち上げた当時にはデータストアとして Master/Slave というものが使われていたのですが、それが deprecated となり、HRD (High Replication Datastore)に1年以内に移行する必要が出てきました。一応別のアプリケーションとして新たに同じコードを deploy したらちゃんと HRD 上でも動いたので移行作業さえ終われば問題はないはずですが・・・。面倒そうな雰囲気だけがありますw

さて今年の開催も含めてどうするか。悩みどころです。