Merge pull request #1321 from spray/wip-IO-WriteFile-rebased
Tcp: introduce WriteFile to support zero-copy writing of files, fixes #2896
This commit is contained in:
commit
cdf717e855
4 changed files with 208 additions and 59 deletions
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
package akka.io
|
||||
|
||||
import java.io.IOException
|
||||
import java.net.{ ConnectException, InetSocketAddress, SocketException }
|
||||
import java.io.{ FileOutputStream, File, IOException }
|
||||
import java.net.{ URLClassLoader, ConnectException, InetSocketAddress, SocketException }
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.channels.{ SelectionKey, Selector, ServerSocketChannel, SocketChannel }
|
||||
import java.nio.channels.spi.SelectorProvider
|
||||
|
|
@ -190,6 +190,29 @@ class TcpConnectionSpec extends AkkaSpec("akka.io.tcp.register-timeout = 500ms")
|
|||
writer.expectMsg(Ack)
|
||||
}
|
||||
|
||||
"write file to network" in withEstablishedConnection() { setup ⇒
|
||||
import setup._
|
||||
|
||||
// hacky: we need a file for testing purposes, so try to get the biggest one from our own classpath
|
||||
val testFile =
|
||||
classOf[TcpConnectionSpec].getClassLoader.asInstanceOf[URLClassLoader]
|
||||
.getURLs
|
||||
.filter(_.getProtocol == "file")
|
||||
.map(url ⇒ new File(url.toURI))
|
||||
.filter(_.exists)
|
||||
.sortBy(-_.length)
|
||||
.head
|
||||
|
||||
// maximum of 100 MB
|
||||
val size = math.min(testFile.length(), 100000000).toInt
|
||||
|
||||
object Ack
|
||||
val writer = TestProbe()
|
||||
writer.send(connectionActor, WriteFile(testFile.getAbsolutePath, 0, size, Ack))
|
||||
pullFromServerSide(size, 1000000)
|
||||
writer.expectMsg(Ack)
|
||||
}
|
||||
|
||||
/*
|
||||
* Disabled on Windows: http://support.microsoft.com/kb/214397
|
||||
*
|
||||
|
|
@ -235,8 +258,8 @@ class TcpConnectionSpec extends AkkaSpec("akka.io.tcp.register-timeout = 500ms")
|
|||
writer.expectMsg(CommandFailed(secondWrite))
|
||||
|
||||
// reject even empty writes
|
||||
writer.send(connectionActor, Write.Empty)
|
||||
writer.expectMsg(CommandFailed(Write.Empty))
|
||||
writer.send(connectionActor, Write.empty)
|
||||
writer.expectMsg(CommandFailed(Write.empty))
|
||||
|
||||
// there will be immediately more space in the send buffer because
|
||||
// some data will have been sent by now, so we assume we can write
|
||||
|
|
@ -607,7 +630,7 @@ class TcpConnectionSpec extends AkkaSpec("akka.io.tcp.register-timeout = 500ms")
|
|||
*/
|
||||
@tailrec final def pullFromServerSide(remaining: Int, remainingTries: Int = 1000): Unit =
|
||||
if (remainingTries <= 0)
|
||||
throw new AssertionError("Pulling took too many loops")
|
||||
throw new AssertionError("Pulling took too many loops, remaining data: " + remaining)
|
||||
else if (remaining > 0) {
|
||||
if (selector.msgAvailable) {
|
||||
selector.expectMsg(WriteInterest)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue