+str #15588,#17229 Java 6 Synchronous File Sink / Source
These are synchronous implementations, because we need to be Java 6 compatible while developing on 2.3.x. However asynchronous implementations using AsynchronousFileChannel will come soon for JDK7 users. + ActorPublisher/Subscriber now manage stopping of the actor + added documentation on configuring dispatcher for File IO + properly handle if source file does not exist + file sink / source come with default io dispatcher > verified no actors are leaking > exceptions are caught and onErrored properly + moved files to akka.stream.io + Added OutputStreamSink and InputStreamSource
This commit is contained in:
parent
a1639c4312
commit
cebd9bf1ae
37 changed files with 1581 additions and 86 deletions
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* Copyright (C) 2015 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
package akka.stream.io.impl
|
||||
|
||||
import java.io.OutputStream
|
||||
|
||||
import akka.actor.{ ActorLogging, Props }
|
||||
import akka.stream.actor.{ ActorSubscriberMessage, WatermarkRequestStrategy }
|
||||
import akka.util.ByteString
|
||||
|
||||
import scala.concurrent.Promise
|
||||
|
||||
/** INTERNAL API */
|
||||
private[akka] object OutputStreamSubscriber {
|
||||
def props(os: OutputStream, completionPromise: Promise[Long], bufSize: Int) = {
|
||||
require(bufSize > 0, "buffer size must be > 0")
|
||||
Props(classOf[OutputStreamSubscriber], os, completionPromise, bufSize)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** INTERNAL API */
|
||||
private[akka] class OutputStreamSubscriber(os: OutputStream, bytesWrittenPromise: Promise[Long], bufSize: Int)
|
||||
extends akka.stream.actor.ActorSubscriber
|
||||
with ActorLogging {
|
||||
|
||||
override protected val requestStrategy = WatermarkRequestStrategy(highWatermark = bufSize)
|
||||
|
||||
private var bytesWritten: Long = 0
|
||||
|
||||
def receive = {
|
||||
case ActorSubscriberMessage.OnNext(bytes: ByteString) ⇒
|
||||
try {
|
||||
// blocking write
|
||||
os.write(bytes.toArray)
|
||||
bytesWritten += bytes.length
|
||||
} catch {
|
||||
case ex: Exception ⇒
|
||||
println("ex = " + ex)
|
||||
bytesWrittenPromise.failure(ex)
|
||||
cancel()
|
||||
}
|
||||
|
||||
case ActorSubscriberMessage.OnError(cause) ⇒
|
||||
log.error(cause, "Tearing down OutputStreamSink due to upstream error, wrote bytes: {}", bytesWritten)
|
||||
context.stop(self)
|
||||
|
||||
case ActorSubscriberMessage.OnComplete ⇒
|
||||
context.stop(self)
|
||||
os.flush()
|
||||
}
|
||||
|
||||
override def postStop(): Unit = {
|
||||
bytesWrittenPromise.trySuccess(bytesWritten)
|
||||
|
||||
if (os ne null) os.close()
|
||||
super.postStop()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue