scalaz iterateeパッケージを使用して、一定のスペースで大きなzipファイルを処理しようとしています。 zipファイルの各ファイルで実行する必要がある、長時間実行されるプロセスがあります。これらのプロセスは並行して実行できます。Scalaz 7大きなzipファイルを処理するためのIteratee(OutOfMemoryError)
File
オブジェクトにそれぞれZipEntry
を膨らませたEnumeratorT
を作成しました。
def enumZipFile(f:File):EnumeratorT[IoExceptionOr[IO[File]], IO]
私は、各ファイルに実行時間の長いプロセスを実行しますIterateeT
を添付したい:シグネチャは次のようになります。私はそれを実行しようとすると
type IOE[A] = IoExceptionOr[A]
def action(f:File):IO[List[Promise[IOE[File]]]] = (
consume[Promise[IOE[File]], IO, List] %=
map[IOE[File], Promise[IOE[File]], IO](longRunningProcess) %=
map[IOE[IO[File]], IOE[File], IO](_.unsafePerformIO) &=
enumZipFile(f)
).run
def longRunningProcess:(iof:IOE[File]):Promise[IOE[File]] =
Promise { Thread.sleep(5000); iof }
:私は基本的にのようなもので終わる
action(new File("/really/big/file.zip")).unsafePerformIO.sequence.get
私はjava.lang.OutOfMemoryError: Java heap space
メッセージが表示されます。それはこれらのすべてのメモリに大量のリストを構築しようとしているので、私には意味があります。IO
とPromise
オブジェクトです。
いくつかの質問:
- 誰もがこれを回避する方法上の任意のアイデアを持っていますか?私は実際にその副作用のために
longRunningProcess
を気にするだけなので、問題に間違って近づいているように感じます。 - ここでは
Enumerator
のアプローチが間違ったアプローチですか?
私はかなり多くのアイディアを持っているので、何か助けになります。
ありがとうございます!ここで
更新#1
は、スタックトレースです:
[error] java.lang.OutOfMemoryError: Java heap space
[error] at scalaz.Free.flatMap(Free.scala:46)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:62)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:61)
[error] at scalaz.effect.IOFunctions$$anon$5.apply(IO.scala:222)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:62)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:61)
[error] at scalaz.effect.IOFunctions$$anon$5.apply(IO.scala:222)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:62)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:61)
[error] at scalaz.effect.IOFunctions$$anon$5.apply(IO.scala:222)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:62)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:61)
[error] at scalaz.effect.IOFunctions$$anon$5.apply(IO.scala:222)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:62)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:61)
[error] at scalaz.effect.IOFunctions$$anon$5.apply(IO.scala:222)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:62)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:61)
[error] at scalaz.effect.IOFunctions$$anon$5.apply(IO.scala:222)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:62)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:61)
[error] at scalaz.effect.IOFunctions$$anon$5.apply(IO.scala:222)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:62)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:61)
[error] at scalaz.effect.IOFunctions$$anon$5.apply(IO.scala:222)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:62)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:61)
[error] at scalaz.effect.IOFunctions$$anon$5.apply(IO.scala:222)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:62)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:61)
[error] at scalaz.effect.IOFunctions$$anon$5.apply(IO.scala:222)
[error] at scalaz.effect.IO$$anonfun$flatMap$1.apply(IO.scala:62)
私は現在、私はそれだと思うようにすべてが機能していることを確認するためにnadavwrのアドバイスを受けています。私は更新を報告します。以下の回答の両方からのアイデアを使用して
更新#2
、私はまともな解決策を見つけました。 huynhjlが示唆したように(そしてnadavwrのヒープダンプ解析の提案を使用して確認した)、consume
はメモリが不足しているため、メモリが不足していました。私はconsume
をfoldM
に変更し、ファイルへの参照の代わりにPromise[IOE[Unit]]
を返すように長期実行プロセスを更新しました。そうすれば、私は最後にすべてのIoExceptionsのコレクションを持っています。
def action(f:File):IO[List[Promise[IOE[Unit]]]] = (
foldM[Promise[IOE[Unit]], IO, List[Promise[IOE[Unit]]]](List.empty)((acc,x) => IO(x :: acc)) %=
map[IOE[File], Promise[IOE[Unit]], IO](longRunningProcess) %=
map[IOE[IO[File]], IOE[File], IO](_.unsafePerformIO) &=
enumZipFile(f)
).run
def longRunningProcess:(iof:IOE[File]):Promise[IOE[Unit]] =
Promise { Thread.sleep(5000); iof.map(println) }
このソリューションは、非同期アップロード中に各エントリを膨張させます。最終的には、エラーを含むPromise
のオブジェクトの膨大なリストがあります。私はまだこれがIterateeの正しい使用であると完全には確信していませんが、私は今私たちのシステムの他の部分で使うことができるいくつかの再利用可能な構成可能な部分を持っています。
ありがとうございました!
長いプロセスは何をしますか? zipコンテンツから何かを計算していますか? – huynhjl
zipファイルの各ファイルはイメージです。長いプロセスは、そのファイルをRackspace CloudFilesにアップロードします。これを理解したら、イメージのサイズを変更してアップロードするプロセスを追加する必要があります。 –
Iterateesは、作業負荷を並列化したいので、このジョブの間違った抽象化のように感じます。俳優たちはもっとうまくいくと思う。 – huynhjl