まっさらなCent OS 4.6でRubyからFlash Lite 1.1を生成するまでのメモ

いろいろやること多くて忘れそうなのでメモ。

Check Installを入れる

RPMを作ってインストールしておいてあげると、あとあと削除や更新が楽チンです。

wget http://www.asic-linux.com.mx/~izto/checkinstall/files/source/checkinstall-1.6.2.tar.gz
tar zxvf checkinstall-1.6.2.tar.gz
cd checkinstall-1.6.2
./configure
make && sudo make install

Check InstallでCheck Installを入れなおす

Check Install自身をRPMから入れなおします。

sudo /usr/local/sbin/checkinstall
sudo rpm -ivh /usr/src/redhat/RPMS/x86_64/checkinstall-1.6.2-1.x86_64.rpm

Rubyを入れる

sudo yum install gcc zlib-devel openssl-devel sqlite-devel
wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p249.tar.gz
tar zxvf ruby-1.8.7-p249.tar.gz
cd ruby-1.8.7-p249
./configure
make
sudo /usr/local/sbin/checkinstall
>> Ruby 1.8.7-p249
sudo rpm -ivh /usr/src/redhat/RPMS/x86_64/ruby-1.8.7-p249-1.x86_64.rpm

Rubygemsを入れる

wget http://rubyforge.org/frs/download.php/60718/rubygems-1.3.5.tgz
tar zxvf rubygems-1.3.5.tgz
cd rubygems-1.3.5
sudo ruby setup.rb

Swf millを入れる

0.2.12を入れる場合、Klabさんが当てているエンコーディングパッチを当てて利用するっぽいんですが、どうやら最新の0.3には取り込まれているらしいです。あと、muraoka17さんの画像関係のパッチも取り込まれている模様。ってことで0.3.0を入れてみました。

sudo yum install libxslt-devel freetype-devel libpng libpng-devel libgcrypt libgcrypt-devel libxml libxml-devel
wget http://swfmill.org/releases/swfmill-0.3.0.tar.gz
tar zxvf swfmill-0.3.0.tar.gz
cd swfmill-0.3.0
./configure
make
sudo /usr/local/sbin/checkinstall
>> Swf mill 0.3.0
sudo rpm -ivh /usr/src/redhat/RPMS/x86_64/swfmill-0.3.0-1.x86_64.rpm

ImageMagickをいれる

wget ftp://ftp.kddlabs.co.jp/graphics/ImageMagick/ImageMagick-6.5.6-10.tar.gz
tar zxvf ImageMagick-6.5.6-10.tar.gz
cd ImageMagick-6.5.6-10
./configure
make
sudo /usr/local/sbin/checkinstall
>> Image Magick 6.5.6-10
sudo rpm -ivh /usr/src/redhat/RPMS/x86_64/ImageMagick-6.5.6-10-1.x86_64.rpm

RMagickをいれる

sudo gem install rmagick --no-ri --no-rdoc

swfmill_ruby

githubから入れるのにgitが必要でした。centosデフォルトのリポジトリにはないので、こちらのリポジトリを追加しました。

sudo yum install git

今度こそと思ったらswfmill_rubyにgemspecがないためインストールできず、forkしてgemspec書いてみたんですがプロジェクトの管理画面にRubyGemsチェックボックスがない!
しょうがないのでローカルでビルドして入れます。

git clone http://github.com/koumiya/swfmill_ruby.git
cd swfmill_ruby
gem build swfmill_ruby.gemspec
# libxmlが必要です。
sudo gem install swfmill_ruby-0.1.gem libxml-ruby

ところどころ思い出し書きなので通らないとこがあるかも!shの補完などでうまくやってください。

UbuntuにFlareとTokyo Cabinet導入

着手中のモバイルアプリで、ユーザー画像のキャッシュを実現するために色々とKVSを検討中です。必要な要件としては、

  • Memcache互換のプロトコルを使える(mod_libmemcached_cacheから使いたい)
  • 有効期限を設定できる
  • 永続化できる
  • なるべく高速

なこと。Tokyo Tyrant(Tokyo Cabinet)が社内での導入実績もあり有力候補だったんですが、なんとMemcahe互換プロトコルだと有効期限が扱えない!ということで、greeさんで提供されているFlareを試してみます。

インストール

基本、チュートリアルに従えばOK。
http://labs.gree.jp/Top/OpenSource/Flare/Document/Installation.html

必要なライブラリ導入

Tokyo Cabinetからbzlib.h(libbz2-dev)が、Flareからboostが必要です。boostはC++の便利ライブラリだそうです。

sudo apt-get install libbz2-dev 'libboost.*-dev' 'libboost.*1.34.1'
Tokyo Cabinetインストール

永続化ストレージとして、Tokyo Cabinetをインストールします。

wget http://1978th.net/tokyocabinet/tokyocabinet-1.4.39.tar.gz
tar zxvf tokyocabinet-1.4.39.tar.gz
cd tokyocabinet-1.4.39/
./configure --prefix=/usr/local/tokyocabinet
make && sudo make install
Flareインストール
wget http://labs.gree.jp/data/source/flare-1.0.9.tgz
tar zxvf flare-1.0.9.tgz
cd flare-1.0.9/
./configure --with-tokyocabinet=/usr/local/tokyocabinet --prefix=/usr/local/flare
make && sudo make install

今日はとりあえずここまで。

シェルで階層ごと特定のファイルをコピー

/usr/local/
          aaa/
              ccc.log
              ddd.txt
          bbb/
              ccc.log
       eee.txt

からccc.logだけを抜き出したい!つまり、こんな感じにしたい。

~/logs/
       aaa/
           ccc.log
    bbb/
           ccc.log

そんなとき用の自分なりの解。忘れないようにメモ。

mkdir ~/logs
cd /usr/local
for d in `ls -p | grep /`; do
mkdir ~/logs/$d
cp $dccc.log ~/logs/$d
done

"ls -p | grep /"でディレクトリだけ抽出できるので、あとは毎ディレクトリごとに作成とコピーを繰り返す。もっとシンプルなやり方ないかなぁ。

シングルトンパターンをクロージャで実装するとオーバーヘッドは減るのか

Life is beautiful: Python Hack : 噛めば噛むほどおいしくなるクロージャの話にて、クロージャを使ってスコープの小さなシングルトンパターンを実装する話が書かれていました。

「if not _config:」という条件分岐を毎回毎回実行しなければならないこと。一つ一つは小さな話でも、何百回も何千回も呼ぶ必要がある場合、このオーバーヘッドも馬鹿にならない(人間だったらすぐに気がついてチェックを辞めるが、プログラムの場合は素直に何度でもチェックしてしまうから)

http://satoshi.blogs.com/life/2009/11/python-hack.html

とあるように、通常シングルトンパターンを実装するときは、インスタンスをロード済みかどうかを毎回チェックする必要があります。

純粋にどのくらいオーバーヘッドがあるのか気になったのと、普段このような実装をしていて無駄だよなぁ…と思っていたので、実際に計測してみました。とりあえず手軽にクロージャが使えるというところでJavascriptで実装しています。

ロード済みかチェックパターン

var Singleton = {
	get:function(){
		if(!this.instance)
			this.instance = {};
		return this.instance;
	}
}
var start = new Date();
for(var i = 0; i < 1000000; i++) {
	Singleton.get();
}
alert(new Date() - start);

クロージャを使ったパターン

var Singleton = {
	get:function(){
		var instance = {};
		this.get = function() { return instance; }
                return this.get();
	}
}
var start = new Date();
for(var i = 0; i < 1000000; i++) {
	Singleton.get();
}
alert(new Date() - start);

計測結果

それぞれ100万回の試行を3回行いその平均値を取りました。その結果は…。

ロード済みかチェックパターン 1746 msec
クロージャを使ったパターン 1669 msec

ということで、その差77msec。わずかではありますが、クロージャを使ったほうが早い。とはいえ、バカにならない程度ではないですね。まぁ、nullチェックなんてそんなもんかと一安心(目をつぶれないほどの差があったら持病の書き直したい病が発病するところだった!) とりあえず、"Javascriptでは"。

逆に、クロージャを使ったほうが遅くなるということはないので、ロード済みのインスタンスを隠蔽できる分優秀ということになりますね。あぁすっきりした。

シルバーウィークにしたいこと

  • ブログを書く!途中まで書いた記事が2本あるのに公開できてない。リリースする。
  • 読書!買ったはいいが学生のときと違って社会人になると時間が有限なのをひしひしと感じる。たまっているミドルウェア、セキュリティ、スケーリング関係の本を消化したい。
  • リア充的ななにかw自分で言っててさみしくなるが、今のとこ友人とIkeaか、季節はずれの海へ。
  • 映画を見る、サマーウォーズ見てからいってないや。
  • 開発合宿!開発中の思考整理ツールを公開…まで持っていきたい!
  • 週末にアイディアを練り上げる週間をつくる。毎週末よろうと思いつつできてない…、テーマは関心のあることなんでもいいから出して→整理して→昇華させるというクセを頭の中につくる。

前にこの本で読んだ。

ひとつ上のアイディア。

ひとつ上のアイディア。

遊びたい!けど、半期ラストスパートかけるよい準備期間でもあるので有効活用したい。とりあえず仕事をきっちり終わらせて気持ちよく休みに入ることが第一の課題だな。

O/R Mapperフレームワークに求めるものメモ

ふぅ。やっと社会人初プロジェクトのリリースが見えてきた。久々のJava案件で何度かRubyに戻りたくなったけど僕は元気です。

ただこれだけはどうしても生産性の面で下せない部分があった。それがO/R Mapper、iBatisを使ってたのだけれど、今まで何度か使ってきたActiveRecord/S2JDBCに比べるとてんでだめ。
逆に、iBatisのほうがMaster/Slaveのサポートなどスケーラビリティのサポートは手厚かったりするのだけど。

今後、O/R Mapperを選ぶ基準みたいなものが浮かびあがってきたので忘れないうちにメモ。

スケーラビリティを確保するためのアドオン

Master/Slave、テーブル分割のサポートなど。
結合の戦略としてJoinにするかfk抽出→Inで問い合わせ
など設定できたら素敵。

少ない設定

アノテーションで設定/適切なデフォルト。

Lazy Loading

S2JDBCからは意識的にけずられている機能だけど、
→結合をきにせずさくっと動くものを作って
→パフォーマンスの問題があればEagerに置き換え
ってサイクルで開発できるので欲しい。

HibernateのようにEntityへの動的プロキシで実装
されたものは高コストなので、関連をたどるコード
を生成してくれるほうがありがたいかも。

いざってときにSQLをかける

このへんはS2JDBCの外出しSQLが素敵。
逆にHQLやらJPQLやらよくわかんないものはNG。

Entityといっしょにメタ情報を提供

フレームワークというよりジェネレータの機能になるけど。
S2JDBCのジェネレータを使うとフィールド名
のメタ情報をEntityNamesというクラスとして提供してくれる。

このメタ情報がいろいろと活用できそう。
例えば複数の社員から社員名だけ抽出したい場合

Entities.extract(employees, EmployeeNames.name);

みたいにタイプセーフに書ける。



こうやって書き出しみると、俺はかなりS2JDBC好きなのが分かるw
LazyLoadingとスケーリングをサポートしてくれたらとりあえず言うことないなぁ。

[Java]Javaでテスト用WEBサーバーを手軽に立てる方法

WEB APIのクライアントプログラムを組んでいると、リクエスト対して適当な値を返してくれるモックサーバーが欲しくなります。RubyだとWebrickを使って簡単にサーバーを立てられるんですが、Javaでやりたい…。

それJettyでできるよ!

Jettyといえば、GAE/Jのプラグインなどで組み込みサーバーとして使われている、注目のPure Java軽量サーバーです。こいつを使います。

なにはともあれコード例を

JUnit4のテストケースから利用する例です。

public class TestCase {
	private static Server server;
		
	@BeforeClass
	public static void prepareServer() throws Exception {
		server = new Server(3000);
		server.addHandler(new AbstractHandler() {
			@Override
			public void handle(String target, HttpServletRequest request,
					HttpServletResponse response, int dispatch) throws IOException,
					ServletException {
				response.setContentType("text/html");
				response.setStatus(HttpServletResponse.SC_OK);
				response.getWriter().write("aaa");
				HttpConnection.getCurrentConnection().getRequest().setHandled(true); 
			}
		});
		server.start();
	}

	@AfterClass
	public static void closeServer() throws Exception {
		server.stop();
		server.destroy();
	}
}

超簡単!!

これだけで3000番でリクエストを待ち受け"aaa"という文字列を返すサーバーが出来上がってしまいました。
handleメソッドの引数targetにリクエストされたパスが入っているので、それに合わせて結果を変えるなんてことも出来ますよ。

Jettyの導入方法

最後にJettyの導入方法を。といっても説明することないくらい簡単です。

1.Jettyのページからライブラリを落としてくる。今回は、jetty-6.1.19.zipを使いました。
2.1を解凍したフォルダ/lib中の3つのjarファイルにクラスパスを通す。

以上です。簡単すぎますね。
H2と組み合わせてポータブルなWEBアプリを作っちゃったりとかいろいろ使い道ありそうですね。Jetty素敵です。