Redis::Fast 0.07 をリリースしました。 現時点での最新バージョンである Redis.pm 1.974 とコンパチブルになります。
主な修正点は以下の通りです
Redis Sentinel 対応 トランザクション内での再接続禁止 再接続にDB選択し直し Redis Sentinel 対応 Redis Sentinel というのは自動フェールオーバーの仕組みらしいです。 (ソースはコピペしたきただけで仕組みはあまり理解していない) どんなものかは本家ドキュメントや実際に検証してみた人の記事をご参照ください。
Redis Sentinel Documentation Redis 2.8 の Sentinel の動きを検証してみた Redis Sentinelを動かしてみた 前から移植作業は進めてたのですが、本家 Redis.pm でもテストがコケたりしてちょっと不安だったのでリリースを見送ってました。 今日 Redis.pm の安定版がリリースされたのでこっちも追従しますよ!!
コネクションを作るときに sentinels を渡すと Redis Sentinel から接続情報を取ってきてくれます。 一緒に reconnect を設定しておいてあげると、Masterに何かあった時に接続情報を再取得→ 自動的に Slave へフェールオーバーしてくれます。
use Redis::Fast; my $redis = Redis::Fast->new( sentinels => [ '127.0.0.1:26379' ], service => 'mymaster', reconnect => 1, ); トランザクション内での再接続禁止 Redisにも簡単なトランザクション機能があって、 複数の命令を同時に実行することができます。 トランザクション中に再接続が発生するとトランザクションがリセットされてしまうので、 接続前の命令を再投入する必要があるのですが、Redis.
Androidのアプリの実態はzipファイルなのでunzipすれば簡単に中身を見ることができるわけですが、 開いてもバイナリファイルが入っているだけでよくわかりません。 AndroidSDKに付属しているaaptというツールを使えば読めるんだけどインストールが大変で苦しんでいる人がいたので、 お手軽に解析できるgolangのライブラリを書いてみました。
使い方 go getしてくる githubのレポジトリ からダウンロードしてきます。
go get github.com/shogo82148/androidbinary AndroidManifest.xmlを解析する io.ReaderAtインターフェースを満たすオブジェクトをandroidbinary.NewXMLFileに渡すと解析してくれます。
f, _ := os.Open("AndroidManifest.xml") xmlFile, _ := androidbinary.NewXMLFile(f) reader := xmlFile.Reader() // reader を読むと普通のXMLファイルとして読める resources.arscを解析する アプリ名などの設定はAndroidManifest.xmlには直接書かれておらず、 リソースファイルに書いてあることがほとんどです(開発者がよほどものぐさでなければ)。 リソースの情報はapk内のresources.arscに書かれているので、 このファイルを読む機能もついてます。
f, _ := os.Open("resources.arsc") tableFile, _ := androidbinary.NewTableFile(f) // ID 0x7F040000 に対応するリソースを読む config := &androidbinary.ResTableConfig{} val, _ := tableFile.GetResource(androidbinary.ResId(0x7f040000), config) アプリ名はロケールによって変わったりするので、 configで設定できます。 例えば日本語の名前を取得したい場合はこんな感じ。
// ID 0x7F040000 に対応するリソース(日本語)を読む config := &androidbinary.ResTableConfig{} config.Language[0] = 'j' config.Language[1] = 'a' val, _ := tableFile.
Tweepyの2.3.0が出ました。 「Tweepy が Application-only Authentication に対応します」僕のprも取り込まれていて、 Application-only Authentication が標準で使えるようになりました。 というわけで、早速遊んでみます。
Application-only Authenticationで遊ぶ 使い方は「tweepyでApplication-only Authenticationしてみた」のときとほぼ同じ。 Tweepy本体に取り込んでもらったので、名前空間がちょこっと変わったくらいです。 Consumer Key と Consumer Secretだけ設定すればいいので、簡単に使えます。
#!/usr/bin/env python # -*- coding: utf-8 -*- import tweepy import codecs import sys sys.stdin = codecs.getreader('utf-8')(sys.stdin) sys.stdout = codecs.getwriter('utf-8')(sys.stdout) CONSUMER_KEY = 'YOUR CONSUMER KEY' CONSUMER_SECRET = 'YOUR CONSUMER SECRET' def main(): user_id = "JO_RI" auth = tweepy.AppAuthHandler(CONSUMER_KEY, CONSUMER_SECRET) api = tweepy.API(auth) arg = {'id': user_id, 'include_rts': 1} user_statuses = tweepy.Cursor(api.user_timeline, **arg).
以前 「tweepyでApplication-only Authenticationしてみた」で 書いたTweepyのAuthHandlerを本体に取り込んでもらいました。 リリースタイミングとかよくわかってないですが、次のリリースとかでApplication-only Authenticationを簡単に使えるようになります、たぶん。
(2014-04-27追記) このprを取り込んだTweepy 2.3.0がリリースされました。早速遊んでみたのでこちらもどうぞ>Tweepyの2.3.0が出ました
取り込まれるまでの経緯 「Application-only Authentication 対応しないの?」って質問は去年からあった(tweepy#318) 先日「ここに動くコード載ってるよ」と僕の記事が紹介される 昨日の夕方「コントリビュートしてみない?」とブログやgithub経由で頼まれる やるしか無い!と思って昨日のうちにpr作成 朝起きたら取り込まれてた 日本語なんてマイナーな言語で記事が書いてあっても、読んでくれる人は読んでくれるんですね。 Tweepy は僕も何度か使ったことがあるので Issue とかみて開発状況をチェックしていたんですが、 見覚えのある名前が見えたときはびっくりしました。
ちょっとしたコードでも公開しておくといいことがあるよ、というお話でした。 最近ここも全然更新してないので、もっとアウトプットしていかないと・・・。
高校生がスパコンを使って5x5の魔方陣の全解を求めたというニュースをきっかけに、 魔方陣の全解列挙が流行っているようです。
高校生がスーパーコンピュータを使って5×5魔方陣の全解を求めることに成功(筑波大プレスリリース) スパコンで約2時間36分かかったという、5×5の魔方陣の全解列挙を、パソコンで試す(C++) 「全解列挙」「数え上げ」「組み合わせ爆発」・・・そして整然とならんだこのマス目・・・ あのおねえさんを思い出しますね。
と、いうわけで、「おねえさんのコンピュータ」の魔方陣版を作ってみました。
おねえさんのコンピュータ(魔方陣編) 「全解列挙をパソコンで試す」の記事と同じような感じで、頭の悪いコードをずらずらと書いてあります。 以下の様な特徴があります。
マスを埋める順番はスパコンで求めたものをベース ただし、対称な位置にあるマスを優先(反転・回転の検索を早い段階で打ち切るため) asm.js による最適化! firefoxで特に高速に動作します わかってはいたけど、asm.jsは人間の書くものではない WebWorkerを使った並列計算 実はまだ5x5の計算結果を見てないのですが、 途中までの計算スピードから推測すると十数時間程度で計算が終わるかと・・・。 (Mac Book Air Mid 2012, 4並列)
コンパイルの手間が無いのでお手軽に試せます。 もっと速いマシンでやればすぐに結果がでてくると思うので、みなさんのレポートお待ちしています。
にゃんぱすー。 最近 C# のコードを見ることが多くなってきました。 開発はVSやMonoDevelop等のIDEを使っているのですが、 diffの確認程度ならgithub上で行っています。 しかし、github上の表示は崩れて非常に読みづらい・・・。
githubのコードプレビューはタブストップが8文字幅で表示されます。 しかし、有名ドコロのIDEはデフォルトがタブインデント、4文字幅で設定されているので、 どうしても表示が狂ってしまいます。 タブインデントではなくスペースインデントを使えば解決☆ なのですが、スペースインデントの中にタブインデントを混入する場合が多々あるので、僕は疲れました・・・。 混在したときのコードなんて、読めたものじゃないですよ。
そこで、githubのタブサイズを変更する Chrome拡張を作ってみました。 ユーザスタイルシートでもできるんですが、まあ、勉強を兼ねて。
GithubTabChange インストール後、github上のレポジトリを開くと≡みたいなマークがURLの横に表示されます。 それをクリックでタブサイズの設定変更が可能です。 githubのプレビューの一斉設定だけでなく、 レポジトリ単位でタブサイズを切り替えることができます。
アイコンとか設定画面のデザインとかちゃんとしたものを作る気力はなかったので、 皆さんのprをお待ちしております。
GithubTabChange on github (これ作ってるときに、githubのHTMLソースの中にtab-size-8というクラスを見つけたのですが、実はどこかに隠し機能としてあるんですかね?)
こんにちは、もうすぐ17才と100ヶ月を迎えるいっちーです。 今朝、Redis::Fast 0.06をリリースしました。 主な変更点はメモリーリークの修正と、エラー発生時にSegmentation Faltで落ちる問題の修正です。
メモリーリーク Redis::Fastをサブスクライバーモードで動作させると、メモリを無限に食い続ける問題をついに!ついに!修正しました。 原因は、一言で言ってしまえば、Perlのリファレンスカウントの扱いの勉強不足です・・・。
XSの中でPerlのオブジェクトを作るとき、プログラマが手動でリファレンスカウントを制御する必要があります。 とはいうものの、全てのオブジェクトのリファレンスカウントを制御するのは大変なので、 XSには「揮発性」という考え方があります。 sv_2motralを使って変数を揮発性に設定しておけば、よしななタイミングでオブジェクトを解放してくれます。 gfx先生のブログにもあるように、 オブジェクト作成したら原則sv_2motralをつけるようにすれば、 メモリーリークはほとんどなくなるはずです。
SV * s = newSVpv("Hello World",0); // Perl の文字列オブジェクト sv_2motral(s) // 揮発性にすることで、使われなくなったら自動的に解放してくれる この「よしななタイミング」をよく理解していなかったのでリークしてました・・・。 XSからオブジェクトへアクセスできなくなったときでないとオブジェクトを解放できないので、 揮発性のオブジェクトが実際に解放されるのは「XSで書かれた関数が終了してPerlに戻るとき」です。 メッセージを待ち続けるwait_for_messages関数は (タイムアウトをしない限り)ずっと終了しないので、 揮発性のオブジェクトを解放するタイミングが一切なかったのです。
不要になったら解放されるよう、揮発性オブジェクトの有効範囲を明示的に指定しました。
sv_2motral(s); ENTER; SAVETMPS; sv_2motral(v); FREETMPS; LEAVE; // v はココで解放される // s は生き残ってる perlcallとかちゃんとドキュメントを読みましょう > 自分
Segmentation Falt 同期的にコマンドを実行してる最中にSIGNAL等で実行が中断されると、 Segmentation Faltが起こる問題を修正しました。 Redis::Fastは同期モードでコマンドを発行したときでも、 hiredisの非同期モードの機能を使って通信しています。 コマンド実行中にエラーが発生すると、 コールバック関数の呼び出しタイミングが変わってしまい、 メモリの確保・解放のタイミングが狂ってしまっていました。
このバグ、試した環境の中ではUbuntu+Perl5.14でしか再現しませんでした。 他の環境ではたまたま解放後もアクセスできてしまって、 正常に動作してしまっていたようです。 嫌なバグだ・・・。
まとめ C言語でメモリ管理するコードは書くべきでない。
みなさんこんにちは、 最近つらいことばかりで元気のないいっちーです。 少しでもつらいことを解消できないかと Unity Test Tools ってので遊んでみました。
背景 最近あったつらいことのひとつに「Unityで作ってるプロジェクトで、機能拡張したときに間違えて一行消しちゃった!!!」 ってのがあります。
もちろん僕が消したわけじゃないですよ!!! 僕サーバサイドエンジニアですから、Unityはいじりません。 でも、一応修正コミットは見ていたはずなので、気がつけなかったのは残念です・・・。
どんなにコード書く人が頑張っても、レビューする人が頑張っても、 人間誰だってミスします。 じゃあ、機械にやらせよう!テストコードだ!って話なんですが、 コードカバレッジが低く、今回のつらい事例でもテストがありませんでした。 一部書いてあるテストも、担当者が代わってからなんか怪しい・・・。
あと、自分も手元でテスト動かしてみたのですが、今のテスト面倒・・・。
Unityのコンソールにドバッと流れる テストが全部通ったのか、失敗したのかよくわからない ユニットテストを1項目だけやりたいとかどうやるんだろう 「テストの実行」が「シーンの再生」なので1項目とかどうすんの? Unity Test Tools つらいので解決方法を探るべくインターネットの海をさまよっていたら Unity Test Tools なるものを発見。
Unity Test Tools Released これを書いてる時点で、3日前のリリースです! タイムリーだ!!
英語でよくわかんないけど、スクリーンショットはわかりやすくてかっこいいぞ! 遊んでみよう!
事前準備 まず、Unity Testing Tools をダウンロードしてこよう! Aseet Store に並んでるので、ダウンロードボタンを押してしばらく待ってれば Unity が勝手に使える状態にしてくれます。
簡単なユニットテストを書いてみる 以前れもんさんが書いた「#24 「Unityでコルーチンも単体テストしよう」 tech.kayac.com Advent Calendar 2012」を Unity Testing Tools でやってみました。
テストの対象はこんな感じのクラスです(短く書けそうな部分があったのでちょっと変えた)。
namespace MyProject { public class Plan { public string Title { get; private set; } public string Text { get; private set; } public Plan(string title, string text) { Title = title; Text = text; } } } れもんさんの記事ではSharpUnitを使っていましたが、 Unity Test Tools は NUnit というテストフレームワークを使うようです。 Plan のテストをNUnitを使って書きなおしてみます。
こんにちは、最近ログの解析をして遊んでいるいっちーです。 解析の結果は最終的にグラフに出すわけなのですが、 先輩方がよく使っているのもあって Google Charts を使ってます。
で、このグラフを他の人に見せると「その元データCSVでちょうだい!」と言われるんです…。
もちろんcsvを作るなんてこと簡単にできるんですが、 今のプログラムにはグラフ用のテンプレートとHTMLで表出力するためのテンプレートとCSV用のテンプレートがあって、 グラフが追加されるたびにコピペして微妙に書き直し、 という不毛な作業が発生してしまうのです。つらい。
Ark::View::DataTable 使い回しの効かないテンプレートとかなんのためのテンプレートなのか。 データだけ用意してあとはそれぞれのテンプレートに入れるだけとなるのが理想的だよねー、と思い続けて早数ヶ月。 ようやく重い腰を上げて Ark::View::DataTableってのを書きました。
使い方 Data::Google::Visualization::DataTable をレンダリングするための ArkのViewです。
use Ark::View::DataTable; use Data::Google::Visualization::DataTable; sub gvis :Local { my ($self, $c) = @_; my $datatable = Data::Google::Visualization::DataTable->new(); $datatable->add_columns( { id => 'x', label => "X", type => 'number' }, { id => 'y', label => "Y", type => 'number' }, ); # 〜〜〜〜正弦波を描きましょう〜〜〜〜 $datatable->add_rows( map { [$_, sin(2*3.1415926535*$_/500)] } 1..1000, ); $c->stash->{table} = $datatable; $c->forward( $c->view( 'DataTable' ) ); } Controllerに感じでかくと使えます。 「/gvis?
ISUCON3の予選を何とか通過し、 本戦へと参戦してきました。
大会中の方針とか考えたこととかメモ。
お題 Tw○tter–likeな画像投稿サービス ユーザをフォローできる フォローしたユーザが画像を投稿すると、タイムラインに画像が流れる 公開範囲を全員に公開・フォロワーのみに公開・自分だけに公開から選べる タイムラインはロングポーリングを使ってリアルタイム反映 JSON-APIが用意されていて、Javascriptから叩く 使用できるサーバは5台 画像を扱うお題と聞いて、会場がざわめきました。
MySQLのクエリを見てみる 開始直後、鍵を用意したり、gitのレポジトリを立てたりなんだりした後、 一回目の計測。
topコマンドで走っているプロセスを見ていると、大量のconvertが!! プロセス名とお題から考えるに、こいつら確実にImage Magickだ・・・。 CPUのほとんどが画像の変換にくわれていたので、 まずは「どこかでキャッシュする」作戦をとることに。 キャッシュするならフロントに近いほうがいいだろうということで、 フロントのnginxでキャッシュする作戦をとることにしました (アクセス制限があるimageは難しいかもしれないけど、全部publicなiconならすぐできるだろうとこのときは思ってました)。
僕はnginxがconvertを駆逐してくれると信じて、MySQLに投げているクエリを中心にPerlのコードを見てました。 役割分担はこんな感じ。
サーバの設定とか(@mackee_wさん) nginxでキャッシュする設定(@9reさん) コード読む、主にMySQLに投げてるクエリとか(@shogo82148) 毎回、ひどいクエリが仕込まれているようなイメージがあったけど、 今回はそこまでひどくない。 クエリチューニング全然効果なさそうと判断して、次の作戦を考えることにしました。
No Image Magick, use Imager! やっぱり一番のボトルネックは画像変換。 nginxでキャッシュするとはいえ軽いほうがいいよね、ということで、 外部プロセスで実行している画像変換をImagerを使ってPerlと同じプロセスでやる作戦。
Imagerに置き換え後ベンチにかけたら、若干スコアが・・・上がった・・・ような・・・? しかし、画像が変化していると怒られて、スコアは無効。 画像エラーを修正するコストと、スコアの上がり具合を見て、Image Magickのままにすることにしました。
予選でも同じように外部プロセス起動している部分をPerlのライブラリにしたけど、 その時はあっさり動いた。 あれは外部プロセス起動をやめたらスコア上がると思い込ませるための布石だったんだ・・・。 (今回の場合、プロセスの起動より画像の変換のほうが重いので、スコアが上がらないのは当たり前)
いろいろ諦めてPerl側でファイルキャッシュ Imagerはテストを通らず、nginxの設定キャッシュ設定も上手く動作しなかったので、 Perlでファイルキャッシュする方針に変更。 convertの結果にmvで適当な場所にコピーして保存。 これだけでスコアが5倍くらいに跳ね上がり、一気に上位に浮上! 最初からやっておくべきだった・・・。 もうちょっと早ければ特別賞もらえたかもしれないのに。
rsync! rsync! ファイルキャッシュの作業をやっている間に、@mackee_wさんがnfsの設定をやってくれたので、 アップロードされたファイルやキャッシュファイルの保存先をnfsに変更。
あとは物量作戦でいくしかないだろうということで、rsyncで他のサーバにコピーして調整を繰り返してた。 (並行してnginxのキャッシュ設定にも再チャレンジしてたけど、nginx力が足りなかった)
最終結果 テストFAILした!! No Score!!
なんかこんなの前もあった!
反省点 画像変換をGETでやってたけど、POSTでやったほうがよかったかも nginxについて勉強しよう nfsについて勉強しよう