2012-01-21 7 views
2

私はEventMachineとEM-SynchronyをREST APIサーバーで使用しています。本体の大きなバイナリファイルを持つPOSTリクエストを受信すると、チャンクで受信し、そのチャンクをTempfileに書き込み、リアクタはブロックしません。EventMachineはチャンク内のファイルを読み書きします

その後、ある時点で、このファイルをチャンクで読み込み、そのチャンクを最終的なファイルに書き込む必要があります。これは機能していますが、期待通りに原子炉をブロックし、ブロックせずに原子炉を動作させる方法を見つけることはできません。

私はそれに一時ファイルと新しいファイル名を渡して、いくつかの時点で、この関数を呼び出す:

def self.save(tmp_file, new_file) 
    tmp = File.open(tmp_file, "rb") 
    newf = File.open(new_file, "wb") 
    md5 = Digest::MD5.new 

    each_chunk(tmp, CHUNKSIZE) do |chunk| 
    newf << chunk 
    md5.update chunk 
    end 

    md5.hexdigest 
end 

def self.each_chunk(file, chunk_size=1024) 
    yield file.read(chunk_size) until file.eof? 
end 

私はEM番号のnext_tickを使用しようと、StackOverflowのでここにすべての他の同様の質問を読んでいます、おそらく解決策(それほど多くのEM経験ではありませんが)はうまくいきません。おそらく私は間違った場所に配置しています。

また、EM#deferを試しましたが、この関数を呼び出してからデータベースの更新を行うと、メインファイルのようにmd5を返す前に読み取り/書き込み処理が完了するまで待つ関数が必要です戻り値を返します。

誰かが私にこれを助けることができたら、私は感謝します。

def copy_and_update(...) 
    checksum = SomeModule.save(temp_file, new_file) 
    do_database_update({:checksum => checksum}) # only with the final md5 value 
end 
:私は機能を保存するだけで、後の私は、最終的なMD5値を待っている呼び出し元の関数のように、ファイルは、読み取り/書き込み完了このような何かを返すことを必要

EDIT 1

+1

'new'はクラスメソッドの名前です。これがモジュールでない限り、それは1つのバグかもしれません。 'new_file'のようなものに変更してテストしてください。 – Linuxios

+0

Whell、そのコードサンプルのちょうど、私はその変数名を使用していません。 –

+0

OK。私はちょうどそれが問題であるかもしれないと思った、最小の問題が最大として現れるかもしれないので。 – Linuxios

答えて

1

は、あなたはそれを破るためにそこに何かを注入する必要があります。

def self.each_chunk(file, chunk_size=1024) 
    chunk_handler = lambda { 
    unless (file.eof?) 
     yield file.read(chunk_size) 


    EM.next_tick(&chunk_handler) 
    end 
    } 

    EM.next_tick(&chunk_handler) 
end 

それはこのようにそれを行うには一種の厄介だが、そのような非同期プログラミングです。

+0

こんにちは、多くの感謝!私はこれが読み取り問題を解決すると思うが、書き込み部分(newf <<チャンク)はどうですか?その反応器をブロックする。 また、ファイルが正常にコピーされていることがわかりましたが、#saveは最初の繰り返しの後にmd5変数を返します。したがって、コピープロセスを待たずに返されるmd5は最初のチャンクのmd5です完了。私は最初の投稿(EDIT 1)を更新しましたので、より簡単に助けてください。 –

+0

EventMachineハンドラを介して読み書きアクティビティをチャンネルする組み込みの方法があることはわかりません。最善の方法は、ブロッキングコールを短くするか、まれに少なくすることです。この場合、OSは書き込みのバッファリングを処理し、IOの問題からあなたを保護する必要があります。 – tadman

関連する問題