nginx + passengerで超適当なRails環境を作る

  • 2010/03/18 ディレクトリを分けた場合のパス指定が間違っていたので修正

自分専用redmineを動かしているサーバが貧弱すぎて、Apache+passengerだと眠くなるくらい遅くなる。
nginxなら少しは軽くなるかなーとか適当に考えて入れてみる。

使った環境:

  • CPU: Atom 230
  • Mem: 2GB

Passengerを入れる

$sudo gem install passenger

nginxの依存モジュールを入れておく

$ sudo apt-get install libpcre3-dev libssl-dev

nginxモジュールを入れる

$ passenger-install-nginx-module

nginxのソースコードのディレクトリと、インストール先のディレクトリを指定。
configureオプションを指定すると、nginxがmakeされる。

nginx.confの編集

nginxモジュールインストール完了後に設定例が出てくるので、その通りに追記。

http {
    ...
    passenger_root /home/user/.gem/ruby/1.8.7/gems/passenger-2.2.4;
    passenger_ruby /local/ruby/1.9.2/bin/ruby1.9;
    ...

    server {
      listen 80;
      server_name example.com;
      root /local/nginx/html/hoge;
      passenger_enabled on;
      passenger_base_uri /hoge;
      # auth_basic "Restricted";
      # auth_basic_user_file htpasswd;
    }
}

通常のディレクトリとRailsのディレクトリをServer Nameで分ける

普通のページとRailsアプリを同時に動かして、どちらにもbasic認証をかけておきたい!
てことで設定変更。
locationの指定に気づくまでに少しかかった。

http {
    ...
    passenger_root /home/user/.gem/ruby/1.8.7/gems/passenger-2.2.4;
    passenger_ruby /local/ruby/1.9.2/bin/ruby1.9;
    ...
    server {
      listen 80;
      server_name example.com;
      root html/hoge;

      location / {
        auth_basic "Restricted";
        auth_basic_user_file htpasswd;
      }
    }
    server {
      listen 80;
      server_name example2.com;
      root html/example2.com;
      passenger_enabled on;
      passenger_base_uri /hoge2;
      rails_env production;

      location / {
        passenger_enabled on;
        auth_basic "Restricted";
        auth_basic_user_file htpasswd;
      }
    }
}

nginxの設定、どこかにまとまった資料とかないかしら。
できれば日本語か英語で・・・

TokyuRubyKaigi#01に行ってきた

当日スタッフとして参加。戦場ビデオカメラマンからカメラを受け取って、録画したりもにょもにょしてました。
以下、感想というか・・・

やったこと

開始前
  • 打ち合わせと軽く買い出し。
  • 設営。主にカメラとiMovieの設定。
LT中
  • 録画スイッチを見つめながらビール & 日本酒
  • 皆様食べ物をたっぷり持ってきてくれてました。
  • こっそりustしてみたり
  • 映像越しにLT見てました。内容は酔ってて覚えてn(ry
終了後
  • 会場片付け・・・中に@kukoさんにご挨拶。
  • 気づいたら片付けほとんど終わってました。ごめんなさい。
その後
  • 品川で2次会的な何か
  • 途中からの記憶がなく、帰りに3度ほど寝過ごすという醜態でした。
  • ご迷惑かけた方がいましたら、本当にすみません。

感想

  • 録画した動画は結構頭が切れてるのが多いです。ごめんなさい。
  • 映像いじったの初めてだったり。各カンファレンスの配信職人の人達はえらいです。すごいです。
  • 義侠(日本酒)うまかった!@koichirooさんありがとうございます!
  • @kukoさんはすばらしい人でしたよ!!!*1


以上、食って飲んでLT聞いてとゆるくて楽しい時間でした。
皆様お疲れ様でした!

*1:書けと言われたので

GREE オープンソーステクノロジー勉強会#19 に行ってきた

Scalaのと書く順番が前後してますが・・・
第19回オープンソーステクノロジー勉強会に行ってきました。
以下、メモ晒しと雑感。

講師: 白石さん@あゆた
html5-developers.jp @google group

HTML5 ってなに?

  • HTML 最新バージョン。新要素、属性が多い。
  • 10 月に最終ドラフト公開。
  • 勧告にはまだまだ遠い (2022 年予定)=>実装されているものから使う。
  • 仕様が分かれている
HTML5 の基本
  • content-type, file extemtion は変わらない
  • タグの種類がすごく増える。
    • 日付、 progress, meter, command etc...
新要素を使ったマークアップ
    • アウトラインを構成する要素
    • スタイル定義の要素には div を使う
    • 独立したセクションの要素
    • RSS で配信されてもいいようなもの

HTML5 では全てがセクションに所属する。
セクションは全て独立した要素である。

アウトライン = セクションの入れ子構造
セクションの構造を意味のある (セマンティックな) 要素で表す
=> プログラムから文書の構造がわかりやすくなる

特徴的な要素
    • 自由にお絵描きができるグラフィック要素
    • 要素の変形などが可能 (js から操作)
    • ex) スピナー画像のサンプル
      • JS 1kb 程度。色の変更や動作の制御が可能
    • 3D がサポートされつつある
フォーム要素
  • 日付やメールアドレス、電話番号などのフォーム要素が増えた
  • Opera では実装が進んでいる
  • 入力値のヴァリデーションが属性値で制御できる。
    • type での自動チェック
    • 正規表現でのチェック
  • オートコンプリートの実装が可能
    • :list => datalist & option
その他の要素
  • ドラッグアンドドロップ API
    • IE での実装を標準か
    • 外部アプリケーションとの連携が可能
    • MIME type を指定してファイルの受け渡しが可能
  • クロスドキュメントメッセージング
    • 異なるウインドウ間でメッセージの受け渡しが可能
    • iframe 内と通信したり
    • ex) iGoogle のガジェット間通信 (ガジェットは iframe)

関連 API

アプリケーションキャッシュ
  • Gears みたいなにローカルにキャッシュができる
Web Database
  • クライアント上で動作する RDB
  • SQL 使用可
  • ドメインごとに領域が分かれている
  • 1 ドメインで複数 DB 保持可
  • 非同期 API と同期型 API が存在する
Web Strage
  • key-value 型のストレージ
  • Local strage: 永続的
  • Session strage: ウインドウごと
  • 既に IE8 で利用可能
Web Workers
  • バックグラウンドで動作するスレッド
  • 複雑になる JS アプリには必須
  • スレッドとは厳密な意味では異なる
    • 変数の共有不可
    • メッセージング API を利用する
    • Worker から DOM をいじるなども不可
  • 辛い点
    • Worker はデバッグ不可。ログ出力もメッセージ API 経由
  • 実装ライブラリ
    • fakeworker.js
    • AlexService
Web Sockets
  • 双方向通信を行う API
  • サーバ側にも専用の実装が必要
    • Port:80, 443
まとめ
  • HTML5+API で Web アプリの可能性が広がる!

雑感

  • ブラウザ自体がアプリケーションプラットフォームになる印象
    • RDBやKVSの内包に注目。
    • インターフェースもさらにリッチにできる。
  • 簡単なアプリはブラウザだけで完結する。サーバサイドは同期するだけになるかも。
  • HTML5 + CSS3 で注目されているが、いつのまにか JS も標準に組み込まれているような。
    • HTML が JS を取り込んだという意見も
    • HTML5 の要素には JS 前提のものが多い
  • とりあえず覚えきれない。仕様でかすぎ。
    • なぜかMS系の環境が連想された。特にExcelとか。

ともあれ、クライアント環境の強化によって、Webアプリケーションの様子ががらりと変わりそうな感じがします。

Scala-hack-a-thon#1に行ってきた

Scala Hack-a-thon #1 : ATND
Scalaやるやる言いつつ全然やれてなかったので、行ってきました。

会場の様子

  • ほぼ満席であったが、恐ろしいほど無言。
  • ただしtwitterは大にぎわい。

やったこと

  • インタプリタはあったけど、エディタとビルド環境を準備してなかったので急いでこしらえる
  • emacs + sbt(Simple-build-tools)
  • 資料の前半部分を読む
  • サンプルコードは帰宅してから読んでみた

雑感

  • とりあえず3時間以上Scalaのことだけ考えられたのはよかった
  • コップ本読んでから行けば良かった
  • Scalaは元々Javaに詳しい人がいじると相当快適じゃないかと思う
    • 逆の場合(つまり俺)はJava+Scalaをやろうとすると、覚えることが多そうだ
    • Scalaの言語仕様はかなり大きい & Javaのライブラリも知っている方がいい

id:yuroyoro さん、参加した皆様お疲れ様でした!
次回はなにか作りに行こうかと思います。

Emacs scala-mode

急いでメモ。

ダウンロード

svn co http://lampsvn.epfl.ch/svn-repos/scala/scala-tool-support/trunk/src/emacs/ scala-mode

設定

;; elispを溜め込んでいるディレクトリが ~/lisp
;; scalaはMacportsでインストール
;; scala-mode
(add-to-list 'load-path "~/lisp/scala-mode")
(add-hook 'scala-mode-hook
          '(lambda ()
             (yas/minor-mode-on)))
(setq yas/scala "~/lisp/scala-mode/contrib/yasnippet/snippets")
(yas/load-directory yas/scala)
(require 'scala-mode-auto)
(setq scala-interpreter "/opt/local/bin/scala")

キーバインド

Evaluate Buffer
C-c C-b
Evaluate Region
C-c C-r
Load file in Interpriter
C-c C-l

ファイルオープン

C-x C-f hoge.scala

ReflectionClassでメソッドを動的に呼ぶ&ベンチマーク

以前に変数を使って、クラスに対して動的にプロパティを追加してみた。
Objectに動的にプロパティを追加する - うっかりプログラミング日誌

今度は動的にメソッドを呼んでみる。*1

<?php
class Test1 {
  public function hoge() {
    return 1 + 1;
  }
}

$test = new Test1();
$method = 'hoge';

$test->$method(); //=> 2

簡単!

ReflectionClassを使う

とはいえ、この方法だと引数が固定数しか取れない。
そこでReflectionMethod#invokeArgsを使う。

<?php
class Test2 {
  public function hoge($a, $b) {
    return $a + $b;
  }
}

$test = new Test2();
$method = 'hoge';
$args = array(1, 3);

$ref = new ReflectionClass(get_class($test));
$met = $ref->getMethod($method); // ReflectionMethodクラスが返される
$met->invokeArgs($test, $args); //=> 4

このReflectionClassが結構便利。
複数のクラスを受け取れるメソッドを用意しておいて、
ReflectionClass#hasMethod()と組み合わせたりすると良い。
ちなみにReflectionMethod#invoke()だと上記の変数呼び出しと同じ使い方になる。

で、遅くないの?

実はここが本題。
動的にメソッドを呼び出すのはいいけど、一体どっちが早いのか?
メソッド呼び出しを100万回くらいやれば速度差が出るかと思い、やってみた。
PEAR::Benchmarkを使っています。

<?php
class Test1 {
  public function hoge() {
    return 1 + 1;
  }
}


require_once('Benchmark/Timer.php');
$timer = new Benchmark_Timer();

$test = new Test1();
$method = 'hoge';
$max = 1000000;

$timer->start();

// 変数呼び出し
for($i=0;$i < $max; $i++) {
  $test->$method();
}
$timer->setMarker('Variable');

// ReflectionClass
for($i=0;$i < $max; $i++) {
  $ref = new ReflectionClass(get_class($test));
  if ($ref->hasMethod($method)) $met = $ref->getMethod($method);
  $met->invoke($test);
}
$timer->setMarker('Reflection');

$timer->stop();
$timer->display();

/*
result
---------------------------------------------------------
marker       time index            ex time         perct   
---------------------------------------------------------
Start        1251959593.35938300   -                0.00%
---------------------------------------------------------
Variable     1251959594.44166300   1.082280         5.83%
---------------------------------------------------------
Reflection   1251959611.91642100   17.474758       94.17%
---------------------------------------------------------
Stop         1251959611.91648500   0.000064         0.00%
---------------------------------------------------------
total        -                     18.557102      100.00%
---------------------------------------------------------
*/

newを含めると、なんと17倍の差が。
純粋にinvokeとの速度差を調べてみました。

<?php
class Test1 {
  public function hoge() {
    return 1 + 1;
  }
}


require_once('Benchmark/Timer.php');
$timer = new Benchmark_Timer();

$test = new Test1();
$method = 'hoge';
$max = 1000000;

$timer->start();

for($i=0;$i < $max; $i++) {
  $test->$method();
}
$timer->setMarker('Variable');

$ref = new ReflectionClass(get_class($test));
if ($ref->hasMethod($method)) $met = $ref->getMethod($method);

for($i=0;$i < $max; $i++) {
  $met->invoke($test);
}
$timer->setMarker('Reflection');

$timer->stop();
$timer->display();

/*
---------------------------------------------------------
marker       time index            ex time         perct   
---------------------------------------------------------
Start        1251959636.48438300   -                0.00%
---------------------------------------------------------
Variable     1251959637.56774800   1.083365        33.69%
---------------------------------------------------------
Reflection   1251959639.69969100   2.131943        66.30%
---------------------------------------------------------
Stop         1251959639.69976100   0.000070         0.00%
---------------------------------------------------------
total        -                     3.215378       100.00%
---------------------------------------------------------
*/

それでもReflectionの方が倍くらいの時間がかかる。

  • クラスやメソッドを解析して、厳密にやるならReflection。
  • チェックとか特に必要なく呼び出せるなら変数。

という感じで使い分けると良さそう。

*1:これの呼び方がよくわからない

array_mapでstaticメソッドを呼び出す時に、selfが使えない

ここのところPHPばかりやっているので、小ネタ。


PHP 5.2.8 for Windows での話。

array_mapで関数名を指定する時、通常は文字列で指定する。

<?php
function _add3($a) {
  return $a + 3;
}
$array = array(1,2,3);
print_r(array_map('_add3', $array));

クラス内の関数の場合はarrayで指定する。

<?php
class Test {
  public function _add3($a) {
    return $a + 3;
  }
  public function hoge($array) {
    return array_map(array($this, '_add3'), $array);
  }
}
$test = new Test();
$array = array(1,2,3);
print_r($test->hoge($array));

インスタンスメソッドが$thisで指定できるなら、staticメソッドはselfでいける!と思ったら・・・

<?php
class Test {
  public static function _add3($a) {
    return $a + 3;
  }
  public function hoge($array) {
    return array_map(array(self, '_add3'), $array);
  }
}
$test = new Test();
$array = array(1,2,3);
print_r($test->hoge($array));

なぜかselfが定義されていない定数というNoticeが出る。

Notice: Use of undefined constant self - assumed 'self' in test.php on line 6

s/self/get_class($this)/
s/self/__CLASS__/

でNoticeは出なくなる。selfの実体は'self'という文字列なので、クラス名の文字列を渡す必要があるコールバック関数では使えないってことかしら。
まあ、E_STRICTを切ればいいんだけど・・・ねえ。

参考

静的なクラスメソッドの場合、 0 番目の要素としてオブジェクトを渡す代わりにクラス名を渡すことにより、 オブジェクトのインスタンスを作成せずに渡すことができます。