だるい。しかし仕事が大詰めなので休むわけにもいかんのがな。
てかもう4月か。有休が12日も消えたわー。毎年10日前後は消えてるんだがー。
4月1日はエイプリルフールとかいって各所のサイトがくそつまらんネタ満載のゴミクズになるのやめてほしい。 クリスマスなんかよりよっぽど有害で中止になればいいのに。中止どころか永遠に消滅すればいいのに。 4月1日のためだけに面白くもないネタを用意するんじゃなくて、日常的に本当に楽しいネタを提供する方に力を注ごうぜ。
ファイルアップロードを改善したいと調べてたんだけど、Uploadifyというのがよさそうだ。 Flashが必要になるけどそもそもPC以外では見れるかどうかすら怪しい作りサイトなので問題ないな。 iOSよりLinuxからの方がアクセス数多いくらいだし。
調べるとAmazon S3への直接アップロード例もいくらかある模様。 ちょっとめんどくさいけどアップロードは肝な部分なのでなんとか入れたいなぁ。
DBにWindows Azure Storage Tableを使ってたんだけど、ADO.NET的な奴は古いAPIなので新しいの使えってことになってたのに気付いて移行。
クエリにLINQ使えないなんてめんどい!と思ったんだけどそんなにクエリ書くところ無かったので大変でもなかった。 本当に使えないのか調べてる方が時間かかるくらいだったわ。
WPFで適当なクライアントも作ってぽちぽち試してた感じではサーバ側の最低限の動作はできたようだ。 しかしランキングもつけないとなーと思ったらStorage Tableは集計できないのでランキングつけるのすごい大変じゃないですか! なんてこった。でもKVSってそういうもんだよな……。
やるならどうしたもんかな。
Workerで集計するのが楽そうだな。 リアルタイムランキングは諦めるしかないが、できる限り頻繁に回せばそれっぽくはなるだろう。 Worker用のインスタンス時間かかるけど3日しか動かさないし。
JavaScriptでのクライアント側も面倒だとか言いながら組んでみたが思ったより簡単にいけた。WPFでクライアント作るより余程簡単だったような気が。 SignalRはやっぱりJavaScriptクライアントで使った方が自然か。.NETクライアントは通信時で一旦JSONにされちゃうのでC#では使いづらかった。 表示にKnockoutJSも使ってるのであまり何も考えずともリアルタイムに表示にまで反映されちゃうのは当然とは言えちょっと不思議な気分だ。
残りの作業は、
くらいが作れたら完成っぽい。今月末までに……見た目ができるか不安だなぁ。
3月は大した変更してないから肉の日リリースを見送ろうとも思ったんだが、思ったよりバグ修正とかしてたので出すことにした。
結構あったな。いくらか補足したい項目があるのでここに書いてしまう。
ぴあきゃす見ながら作業してたら見てたチャンネルに接続できなくなって、しかしスレの様子では他の人は見れているようなので調査したらバグだったので修正した。
トラッカーに接続した時にいっぱいだからここにつなげリストを貰うんだが、その先に接続したら404(そんなチャンネル持ってないです)を返されて接続を諦めてしまっていた。トラッカーに接続して404が返ってきたらさすがに諦めるしかないんだが、トラッカーでなければ他の接続先に試しにいかないといけないはず。 調べるとハンドシェイクが行われるまで現在の接続先情報が設定されず、接続エラーはトラッカーかどうか判別できないので終わるということにしてしまっていた。 接続先候補リストから選んでるので接続先情報持ってるだろ、これちゃんと使えよ。ということでトラッカー以外が404を返してきてもちゃんと他にフォールバックするように修正できた。これけっこうでかい問題だったわ。
修正はできたんだけど、実はもう一個大きい問題が残っている。 トラッカーが接続先候補として渡してくるのに、いざ接続に行くと404を返してくるノードがいることだ。
これが短時間であればたまたまそのタイミングで見るのやめたとかで普通に起きるので問題ないんだけど、確実に10分以上はこの状況のままだった。普通のPeerCastだとたしか30秒くらいだかPeerCastStationでも3分くらいで更新されないノード情報は消してるので、もう接続されていないノードは3分もすれば接続先候補として返してくるわけはない。ということは接続はされていて自分のノード情報を定期的にトラッカーに送信しているのだろう。しかしいざリレー要求しに行くと404を返す。おいちょっとひどいよ。
普通のPeerCastやPeerCastStationで長期間そんな状態になることはないのでなんらかのツールを使ってるんだと思うんだけど、なんのツールなんだろう。UserAgentもほとんどがVP版を名乗るので区別つかないんだよなぁ。てか正常なふりしてリレーできないのは行儀悪すぎるんでやめてくれそれは。PeerCastちゃんは生まれつき病弱でひどい動きをするノードにとても弱いので優しくしてあげてください。
ちゃんと実装はめんどくさいかもしれませんが、そのめんどくさいが簡単に致命傷になれるので気をつけてください。 ツールを作る場合はPeerCastStationをライブラリとして使うのがおすすめです。ドキュメントがないけどな……。
PeerCast(およびPeerCastStation)は誰かに接続しに行った時に相手に接続してもらってポート開いてるかどうか自分で把握するんだけど、一旦ポート開いてる/閉じてるが確定するとポート設定を変更しても再起動しても変わらんという報告をもらっていたので対応した。
PeerCastではポート設定を変更するには一旦サーバを落とさないといけないので問題なかったんだけど、PeerCastStationだとリレーしてようがなんだろうがポート設定変更できちゃうので問題になったようだ。なるほどなー。それならばと設定変更した時には確認したポート状態を未確定に戻すようにした。だけ。
外のファイアウォール設定が変わったとかはさすがに検知できないしそこまでは期待されてないだろうからこれでいいでしょう。
設定されてるポートにBindできなかった時は接続待ち受け無しで立ち上がるんだけど、接続待ち受け無しだとHTML UIにも接続できなくてこまる。 GUIがあればいいんだけどGUI無しだとポート設定変更もできなくてどうしたものかなーと。
どう解決したものかずっと悩んでいたんだけど、Bindできる適当なポートで接続待ち受けしてそこで設定変更してもらえばいいじゃんと思いついて実装した。 まあ現状だとGUI無いとどのポートで待ち受けたのかもわからんので結局意味無いんだけど、そのうちなんとかすることはできるだろう。
1.2.0で設定ファイルのフォーマットを変更したんだけど、WPF版GUIを入れてみたら失敗したことに気付いた。
WCFのDataContractSerializerを使って設定をXMLにシリアライズしてたんだが、これ知らないクラスはデシリアライズできないんだよな。まあ当然だけど。 で、Windows.Forms版のGUI設定が入った設定ファイルをWPF版GUIで読もうとするとデシリアライズに失敗してもうた。あらら。
DataContractSerializerでどう処理したらいいかわからん部分を適当に読み込んで保持しておいたりできないか調べたが、どうも調べた感じでは無理なようだ。 そもそもそんなことするような物じゃねーってな。
Rubyなんかでは簡単に書けてたような気がするがどうしてたんだっけ?と思い起こすと適当にYAMLなんかに詰め込んだりするようなメソッドを作ってた気がする。 つまり自前シリアライザをさくっと作ってたってことか。観念して自前シリアライザ作るしかなさそうだな。
なんで俺はXMLへのシリアライザなんか自前で作ってるんだという気になりながらも途中で楽しくなってだいたい完成した。素のシリアライザは書けたんだが、知らないクラスがシリアライズされてた場合の処理がまだ書けてない。ここが自前シリアライザを作った理由なんだからちゃんと書かないとな。といっても単に読み込めたけどデシリアライズできなかったオブジェクトはそのまま値を保持しておいて、書き出すときにはそのまま書き戻してあげればいいだけなんだが。
フォーマットを変えるのはべつにいいんだけど、短時間でころころフォーマット変えちゃうとちゃんと設定が引き継がれるか不安なんだよなぁ。