2012年2月11日土曜日

ScalaのActorとsleep

ScalaのActorの中でThread.sleepを使っていたら、どうも平行に処理されていないような気がして調べてみました。

 例えば、javaのThreadを使って以下のようなコードを実行する。
      1 to 10 map( n => (new Thread() {
 override def run = {
   println("start "+n)
   Thread.sleep( 3000 )
   println("done "+n)
 }
      }).start )
結果の出力は、以下のように、ほぼ同時に10個のスレッドがスタートして、 3秒後にそれぞれ終了する。
これは、予想通り。
start 10
start 4
start 6
start 2
start 3
start 8
start 9
start 7
start 1
start 5
done 10
done 4
done 6
done 2
done 3
done 8
done 9
done 7
done 1
done 5
これをActorを使って書き換える。
      1 to 10 map( n => Actor.actor {
 println("start "+n)
 Thread.sleep( 3000 )
 println("done "+n)
      })
このコードを実行した結果。
start 1
start 6
start 8
start 7
start 3
start 5
start 2
start 4
done 1
done 6
done 8
start 9
start 10
done 3
done 7
done 4
done 2
done 5
done 9
done 10
この結果をみると、最初の8個のスレッドは、ほぼ同時にスタートしているのがわかるが、 残りの2つは、最初にスタートしたスレッドが終わるのを待ってから、3秒後にそれぞれスタートしている。 

なぜ? 

どうやらこれはActorのプールに関係しているらしい。
 詳しくは分からないが、Thread.sleepを使った場合、 並列に実行できるのは、CPUのスレッド数のみのようだ。
それ以上に、並列に実行したいので、Thread.sleepを使わずに、 receiveWithinを使ったらうまくいった。
      1 to 10 map( n => Actor.actor {
 println("start "+n)
 Actor.self.receiveWithin( 3000 ) { case TIMEOUT => {}}
 println("done "+n)
      })
仕方ないので、この方法でやるかなぁ。

2012年2月10日金曜日

Liftでのプロパティファイル扱い

Liftのアプリケーションでいくつかのプロパティファイルを使い分けたい場合があります。
例えば、本番環境とテスト環境でDBの接続先を変えたい場合などです。
そうした場合、Liftは、プロパティファイルの名前によって使用するプロパティファイルを決めているようです。 基本的な、命名規則は、
modeName.userName.hostName.props
で、名前によって以下の順で優先的に読まれます。
/props/modeName.userName.hostName.props
/props/modeName.userName.props
/props/modeName.hostName.props
/props/modeName.default.props
/modeName.userName.hostName.props
/modeName.userName.props
/modeName.hostName.props
/modeName.default.props

nodeNameは、使用しているRun Modeのことで、例えば、"test"、"staging"、"production"、"profile"などを指定します。
"development"モードを使っている場合は、nodeNameは、省略してください。nodeNameに"development"って書いちゃうと、"development"モードとして正しく認識されないので注意が必要です。

userNameは、使っているOSのユーザ名にしなければならないようです。

 私の場合は、自分のローカルPCでは、リポジトリにあがっているプロパティファイルではなく 独自のプロパティファイルを使いたいので、自分の名前のプロパティファイルを作っています。
リポジトリにあがっているものは、本番で使うプロパティファイルで、 default.propsという名前にしてて、自分のPCでは、hogehoge.propsという名前にして、これはリポジトリの管理下においていません。

2012年2月6日月曜日

Emacsでclojure開発環境を整える

Emacsにclojureの開発を整えた時のメモ。

clojure-modeのインストール

  • EmacsでM-x package-install clojure-modeを実行する
  • init.elを編集
  • ;; clojure mode
    (require 'clojure-mode)
    
    ;; paredit
    (defun turn-on-paredit () (paredit-mode 1))
    (add-hook 'clojure-mode-hook 'turn-on-paredit)
    

slimeのインストール

  • EmacsでM-x package-list-packageを実行
  • slimeとslime-replにカーソルを合わせてiを押す
  • xを押してインストールを実行

Leiningenインストール

Leiningenは、clojureのビルドツール。
  • ここのページのDownload the scriptからシェルスクリプトをダウンロードしてくる
  • $> wget https://raw.github.com/technomancy/leiningen/stable/bin/lein
    
  • 権限を変えてパスの通った場所に置く
  • $> chmod 755 lein
    $> sudo mv lein /usr/bin/.
    

swank clojureのインストール

  • 以下のコマンドを実行してインストール
  • $> lein plugin install swank-clojure 1.4.0
    

プロジェクトの作成

$> lein new projectname

Emacsでreplを起動

 M-x clojure-juck-in

開いているバッファをコンパイル

 C-c C-k

EmacsにMarmaladeをインストール

Emacsのパッケージ管理システムであるMarmaladeをインストールしてみました。
  • Marmaladeからpackage.elを取得する
  • $> cd ~/.emacs.d/elisp
    $> wget http://repo.or.cz/w/emacs.git/blob_plain/1a0a666f941c99882093d7bd08ced15033bc3f0c:/lisp/emacs-lisp/package.el
    
  • init.elにmarmaladeの設定をする
  • (require 'package)
    (add-to-list 'package-archives
                 '("marmalade" . "http://marmalade-repo.org/packages/"))
    (package-initialize)
    
  • EmacsでM-x package-list-packageとするとインストールできるパッケージのリストが表示される
  • インストールしたいパッケージにカーソルを合わせてiを押せば選択できる
  • xでインストールを実行する