Python+Rubyつづき
2007.11.22 Thursday 22:41
先日のRuby+Pythonのファイル再圧縮ソフトのファイル名一覧作成をRuby側に移してみた.そしてRubyは文字コードの配慮が必要だと気づく.さらにRubyのFind.find()はすべてのファイルにstatするので,ネットワークドライブだと遅すぎて使えない.
結局OSの機能に頼ることに.さらにMVCフレームワークは人間相手ではない分散処理のサーバとしては適切でないことを認識した.
結局OSの機能に頼ることに.さらにMVCフレームワークは人間相手ではない分散処理のサーバとしては適切でないことを認識した.
前回のバージョンには十分な空き容量(10GB以上)のPCでないと作業中にディスク不足になるという問題があった.そこで(展開後の)ファイルサイズを確認してDBに登録し,空き領域に入らないサイズのファイルを渡さないように変更した.
ファイルサイズの確認には書庫のスキャンが必要なため,この処理もRubyのwork taskの方で行うようにしたところで問題点にぶつかった.
Rubyで空き容量を取得するにはどうすればよいか.UNIXならdfを呼び出せばよい.WindowsではWMIを使うのがよいようだ.MLの投稿記事
ファイルリスト作成処理を最初Findを使って作ったのだが,動かしてみると途中でフリーズ(にみえる).Filemon(Sysinternals)を使ってファイルアクセス状況を見たら,ネットワークドライブ上にある多量のファイルに対して1つずつ情報を取得していた.1秒間に2個くらいしか進んでいない.ファイルは1000個以上あるので終わらないはずだ.
find.rbで使われているFile.exists?()とFile.directory?()が原因と思われるのでこれを何とか除去したい.しかしRubyではディレクトリのみを一括取得することはできなさそう.
仕方がないのでwin32oleを使ってWSHのFileSystemObjectを呼び出すことにした.File.exists?はファイルごとの処理でファイルが削除された場合に備えたものと思われるが,今回はファイルを消すことはないのでこの処理は不要.File.directory?()はファイル一覧を作成するときに FileSystemObject.GetFolder().SubFolders で取得したリストと照合してディレクトリかどうかを事前判定することで除去.
これで格段に速くなった.しかし,Windows専用になってしまった.
ソースコード
Rubyでファイルリストを作成してPyhonのサーバに送りつけたらPython側でUnicodeError ... simple-json.rbの説明には「入力はUTF-8」とかかれている.しかし,Dir.open()で取得されるファイル名はShift-JIS.$KCODEを変えてもここは変わらない.
仕方がないので,必要に応じてIconvで変換することに.システムの規定のコードを取得する方法がないかと探したが見つからず断念.あきらめてcp932と直接記入.
今回サーバ側にDjango(Python)を使ったのは失敗だった.Djangoの制約もあるが,atomic性(同一処理を複数回払い出してしまわない)の保証をunique属性をつけた別のテーブルで行ってみたが,やはり無理がある.かといって,Webサーバ上でこの処理がマルチプロセスで動くことを考えるとDB以外に信頼できるロック機構はありえない.
Djangoの内蔵webサーバは開発用ということもあって同時に1つのリクエストしか受け付けられない.運用はまっとうなWebサーバ+mod_python or fcgi or wsgi ということになっている.このあたりはRuby on Railsでも同じである.
こちらの記事を読むと,Erlangを使うべきだったと思えてくる.
普通Webシステムでは個々のユーザ間で状態遷移の競合が起こることはない.二人が同時にコメントを書いたとしてもその順序が問題にはならない.しかし,Queueのように先頭から早い者勝ちで取る仕組みでは本質的に競合してしまうので整理人を使う方が合理的だ.
ErlangのWebサーバYawsは非同期処理で複数のリクエストを受け付けられる上,DBで行っている処理のatomic性も専用の(Erlang)プロセスに処理させれば一貫性が崩れることはない.記事中でかかれている組み込みDBとWeb出力の扱いについて調べれば十分使えそうである.
ファイルサイズの確認には書庫のスキャンが必要なため,この処理もRubyのwork taskの方で行うようにしたところで問題点にぶつかった.
空き容量の取得
Rubyで空き容量を取得するにはどうすればよいか.UNIXならdfを呼び出せばよい.WindowsではWMIを使うのがよいようだ.MLの投稿記事
Find
ファイルリスト作成処理を最初Findを使って作ったのだが,動かしてみると途中でフリーズ(にみえる).Filemon(Sysinternals)を使ってファイルアクセス状況を見たら,ネットワークドライブ上にある多量のファイルに対して1つずつ情報を取得していた.1秒間に2個くらいしか進んでいない.ファイルは1000個以上あるので終わらないはずだ.
find.rbで使われているFile.exists?()とFile.directory?()が原因と思われるのでこれを何とか除去したい.しかしRubyではディレクトリのみを一括取得することはできなさそう.
仕方がないのでwin32oleを使ってWSHのFileSystemObjectを呼び出すことにした.File.exists?はファイルごとの処理でファイルが削除された場合に備えたものと思われるが,今回はファイルを消すことはないのでこの処理は不要.File.directory?()はファイル一覧を作成するときに FileSystemObject.GetFolder().SubFolders で取得したリストと照合してディレクトリかどうかを事前判定することで除去.
これで格段に速くなった.しかし,Windows専用になってしまった.
ソースコード
文字コード
Rubyでファイルリストを作成してPyhonのサーバに送りつけたらPython側でUnicodeError ... simple-json.rbの説明には「入力はUTF-8」とかかれている.しかし,Dir.open()で取得されるファイル名はShift-JIS.$KCODEを変えてもここは変わらない.
仕方がないので,必要に応じてIconvで変換することに.システムの規定のコードを取得する方法がないかと探したが見つからず断念.あきらめてcp932と直接記入.
今回サーバ側にDjango(Python)を使ったのは失敗だった.Djangoの制約もあるが,atomic性(同一処理を複数回払い出してしまわない)の保証をunique属性をつけた別のテーブルで行ってみたが,やはり無理がある.かといって,Webサーバ上でこの処理がマルチプロセスで動くことを考えるとDB以外に信頼できるロック機構はありえない.
Djangoの内蔵webサーバは開発用ということもあって同時に1つのリクエストしか受け付けられない.運用はまっとうなWebサーバ+mod_python or fcgi or wsgi ということになっている.このあたりはRuby on Railsでも同じである.
こちらの記事を読むと,Erlangを使うべきだったと思えてくる.
普通Webシステムでは個々のユーザ間で状態遷移の競合が起こることはない.二人が同時にコメントを書いたとしてもその順序が問題にはならない.しかし,Queueのように先頭から早い者勝ちで取る仕組みでは本質的に競合してしまうので整理人を使う方が合理的だ.
ErlangのWebサーバYawsは非同期処理で複数のリクエストを受け付けられる上,DBで行っている処理のatomic性も専用の(Erlang)プロセスに処理させれば一貫性が崩れることはない.記事中でかかれている組み込みDBとWeb出力の扱いについて調べれば十分使えそうである.
Comments