PageRenderTime 1557ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/akka-actor/src/main/scala/akka/actor/IO.scala

https://github.com/lossyrob/akka
Scala | 1227 lines | 591 code | 145 blank | 491 comment | 70 complexity | 883e2e69a4ce9c3df203ec329dc9874f MD5 | raw file
Possible License(s): Apache-2.0
  1. /**
  2. * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
  3. */
  4. package akka.actor
  5. import language.higherKinds
  6. import language.postfixOps
  7. import scala.concurrent.{ ExecutionContext, Future }
  8. import scala.concurrent.duration.Duration
  9. import scala.util.control.NonFatal
  10. import akka.util.ByteString
  11. import java.net.{ SocketAddress, InetSocketAddress }
  12. import java.nio.ByteBuffer
  13. import java.nio.channels.{
  14. SelectableChannel,
  15. ReadableByteChannel,
  16. WritableByteChannel,
  17. SocketChannel,
  18. ServerSocketChannel,
  19. Selector,
  20. SelectionKey,
  21. CancelledKeyException
  22. }
  23. import scala.collection.mutable
  24. import scala.annotation.tailrec
  25. import scala.collection.generic.CanBuildFrom
  26. import java.util.UUID
  27. import java.io.{ EOFException, IOException }
  28. import akka.actor.IOManager.Settings
  29. import akka.actor.IO.Chunk
  30. /**
  31. * IO messages and iteratees.
  32. *
  33. * This is still in an experimental state and is subject to change until it
  34. * has received more real world testing.
  35. */
  36. object IO {
  37. final class DivergentIterateeException extends IllegalStateException("Iteratees should not return a continuation when receiving EOF")
  38. /**
  39. * An immutable handle to a Java NIO Channel. Contains a reference to the
  40. * [[akka.actor.ActorRef]] that will receive events related to the Channel,
  41. * a reference to the [[akka.actor.IOManager]] that manages the Channel, and
  42. * a [[java.util.UUID]] to uniquely identify the Channel.
  43. */
  44. sealed trait Handle {
  45. this: Product
  46. def owner: ActorRef
  47. def ioManager: ActorRef
  48. def uuid: UUID
  49. override lazy val hashCode = scala.runtime.ScalaRunTime._hashCode(this)
  50. def asReadable: ReadHandle = throw new ClassCastException(this.toString + " is not a ReadHandle")
  51. def asWritable: WriteHandle = throw new ClassCastException(this.toString + " is not a WriteHandle")
  52. def asSocket: SocketHandle = throw new ClassCastException(this.toString + " is not a SocketHandle")
  53. def asServer: ServerHandle = throw new ClassCastException(this.toString + " is not a ServerHandle")
  54. /**
  55. * Sends a request to the [[akka.actor.IOManager]] to close the Channel
  56. * associated with this [[akka.actor.IO.Handle]].
  57. *
  58. * This can also be performed by sending [[akka.actor.IO.Close]] to the
  59. * [[akka.actor.IOManager]].
  60. */
  61. def close(): Unit = ioManager ! Close(this)
  62. }
  63. /**
  64. * A [[akka.actor.IO.Handle]] to a ReadableByteChannel.
  65. */
  66. sealed trait ReadHandle extends Handle with Product {
  67. override def asReadable: ReadHandle = this
  68. }
  69. /**
  70. * A [[akka.actor.IO.Handle]] to a WritableByteChannel.
  71. */
  72. sealed trait WriteHandle extends Handle with Product {
  73. override def asWritable: WriteHandle = this
  74. /**
  75. * Sends a request to the [[akka.actor.IOManager]] to write to the
  76. * Channel associated with this [[akka.actor.IO.Handle]].
  77. *
  78. * This can also be performed by sending [[akka.actor.IO.Write]] to the
  79. * [[akka.actor.IOManager]].
  80. */
  81. def write(bytes: ByteString): Unit = ioManager ! Write(this, bytes)
  82. }
  83. /**
  84. * A [[akka.actor.IO.Handle]] to a SocketChannel. Instances are normally
  85. * created by [[akka.actor.IOManager]].connect() and
  86. * [[akka.actor.IO.ServerHandle]].accept().
  87. */
  88. case class SocketHandle(owner: ActorRef, ioManager: ActorRef, uuid: UUID = UUID.randomUUID()) extends ReadHandle with WriteHandle {
  89. override def asSocket: SocketHandle = this
  90. }
  91. /**
  92. * A [[akka.actor.IO.Handle]] to a ServerSocketChannel. Instances are
  93. * normally created by [[akka.actor.IOManager]].listen().
  94. */
  95. case class ServerHandle(owner: ActorRef, ioManager: ActorRef, uuid: UUID = UUID.randomUUID()) extends Handle {
  96. override def asServer: ServerHandle = this
  97. /**
  98. * Sends a request to the [[akka.actor.IOManager]] to accept an incoming
  99. * connection to the ServerSocketChannel associated with this
  100. * [[akka.actor.IO.Handle]].
  101. *
  102. * This can also be performed by creating a new [[akka.actor.IO.SocketHandle]]
  103. * and sending it within an [[akka.actor.IO.Accept]] to the [[akka.actor.IOManager]].
  104. *
  105. * @param options Seq of [[akka.actor.IO.SocketOptions]] to set on accepted socket
  106. * @param socketOwner the [[akka.actor.ActorRef]] that should receive events
  107. * associated with the SocketChannel. The ActorRef for the
  108. * current Actor will be used implicitly.
  109. * @return a new SocketHandle that can be used to perform actions on the
  110. * new connection's SocketChannel.
  111. */
  112. def accept(options: Seq[SocketOption] = Seq.empty)(implicit socketOwner: ActorRef): SocketHandle = {
  113. val socket = SocketHandle(socketOwner, ioManager)
  114. ioManager ! Accept(socket, this, options)
  115. socket
  116. }
  117. }
  118. /**
  119. * Options to be set when setting up a [[akka.actor.IO.SocketHandle]]
  120. */
  121. sealed trait SocketOption
  122. /**
  123. * Options to be set when setting up a [[akka.actor.IO.ServerHandle]]
  124. */
  125. sealed trait ServerSocketOption
  126. /**
  127. * [[akka.actor.IO.SocketOption]] to enable or disable SO_KEEPALIVE
  128. *
  129. * For more information see [[java.net.Socket.setKeepAlive]]
  130. */
  131. case class KeepAlive(on: Boolean) extends SocketOption
  132. /**
  133. * [[akka.actor.IO.SocketOption]] to enable or disable OOBINLINE (receipt
  134. * of TCP urgent data) By default, this option is disabled and TCP urgent
  135. * data received on a [[akka.actor.IO.SocketHandle]] is silently discarded.
  136. *
  137. * For more information see [[java.net.Socket.setOOBInline]]
  138. */
  139. case class OOBInline(on: Boolean) extends SocketOption
  140. /**
  141. * [[akka.actor.IO.SocketOption]] to set performance preferences for this
  142. * [[akka.actor.IO.SocketHandle]].
  143. *
  144. * For more information see [[java.net.Socket.setPerformancePreferences]]
  145. */
  146. case class PerformancePreferences(connectionTime: Int, latency: Int, bandwidth: Int) extends SocketOption with ServerSocketOption
  147. /**
  148. * [[akka.actor.IO.SocketOption]] to set the SO_RCVBUF option for this
  149. * [[akka.actor.IO.SocketHandle]].
  150. *
  151. * For more information see [[java.net.Socket.setReceiveBufferSize]]
  152. */
  153. case class ReceiveBufferSize(size: Int) extends SocketOption with ServerSocketOption {
  154. require(size > 0, "Receive buffer size must be greater than 0")
  155. }
  156. /**
  157. * [[akka.actor.IO.SocketOption]] to enable or disable SO_REUSEADDR
  158. *
  159. * For more information see [[java.net.Socket.setReuseAddress]]
  160. */
  161. case class ReuseAddress(on: Boolean) extends SocketOption with ServerSocketOption
  162. /**
  163. * [[akka.actor.IO.ServerSocketOption]] to set the maximum backlog of connections. 0 or negative means that the platform default will be used.
  164. * For more information see [[http://docs.oracle.com/javase/7/docs/api/java/nio/channels/ServerSocketChannel.html#bind(java.net.SocketAddress, int)]]
  165. * @param numberOfConnections
  166. */
  167. case class Backlog(numberOfConnections: Int) extends ServerSocketOption
  168. /**
  169. * [[akka.actor.IO.SocketOption]] to set the SO_SNDBUF option for this
  170. * [[akka.actor.IO.SocketHandle]].
  171. *
  172. * For more information see [[java.net.Socket.setSendBufferSize]]
  173. */
  174. case class SendBufferSize(size: Int) extends SocketOption {
  175. require(size > 0, "Send buffer size must be greater than 0")
  176. }
  177. /**
  178. * [[akka.actor.IO.SocketOption]] to enable or disable SO_LINGER with the
  179. * specified linger time in seconds.
  180. *
  181. * For more information see [[java.net.Socket.setSoLinger]]
  182. */
  183. case class SoLinger(linger: Option[Int]) extends SocketOption {
  184. if (linger.isDefined) require(linger.get >= 0, "linger must not be negative if on")
  185. }
  186. /**
  187. * [[akka.actor.IO.SocketOption]] to set SO_TIMEOUT to the specified
  188. * timeout rounded down to the nearest millisecond. A timeout of
  189. * zero is treated as infinant.
  190. *
  191. * For more information see [[java.net.Socket.setSoTimeout]]
  192. */
  193. case class SoTimeout(timeout: Duration) extends SocketOption {
  194. require(timeout.toMillis >= 0, "SoTimeout must be >= 0ms")
  195. }
  196. /**
  197. * [[akka.actor.IO.SocketOption]] to enable or disable TCP_NODELAY
  198. * (disable or enable Nagle's algorithm)
  199. *
  200. * For more information see [[java.net.Socket.setTcpNoDelay]]
  201. */
  202. case class TcpNoDelay(on: Boolean) extends SocketOption
  203. /**
  204. * [[akka.actor.IO.SocketOption]] to set the traffic class or
  205. * type-of-service octet in the IP header for packets sent from this
  206. * [[akka.actor.IO.SocketHandle]].
  207. *
  208. * For more information see [[java.net.Socket.setTrafficClass]]
  209. */
  210. case class TrafficClass(tc: Int) extends SocketOption {
  211. require(tc >= 0, "Traffic class must be >= 0")
  212. require(tc <= 255, "Traffic class must be <= 255")
  213. }
  214. /**
  215. * Messages used to communicate with an [[akka.actor.IOManager]].
  216. */
  217. sealed trait IOMessage
  218. /**
  219. * Message to an [[akka.actor.IOManager]] to create a ServerSocketChannel
  220. * listening on the provided address with the given
  221. * [[akka.actor.IO.ServerSocketOption]]s.
  222. *
  223. * Normally sent using IOManager.listen()
  224. */
  225. case class Listen(server: ServerHandle, address: SocketAddress, options: Seq[ServerSocketOption] = Seq.empty) extends IOMessage
  226. /**
  227. * Message from an [[akka.actor.IOManager]] that the ServerSocketChannel is
  228. * now listening for connections.
  229. *
  230. * No action is required by the receiving [[akka.actor.Actor]].
  231. */
  232. case class Listening(server: ServerHandle, address: SocketAddress) extends IOMessage
  233. /**
  234. * Message from an [[akka.actor.IOManager]] that a new connection has been
  235. * made to the ServerSocketChannel and needs to be accepted.
  236. */
  237. case class NewClient(server: ServerHandle) extends IOMessage
  238. /**
  239. * Message to an [[akka.actor.IOManager]] to accept a new connection with the
  240. * given [[akka.actor.IO.SocketOption]]s.
  241. *
  242. * Normally sent using [[akka.actor.IO.ServerHandle]].accept()
  243. */
  244. case class Accept(socket: SocketHandle, server: ServerHandle, options: Seq[SocketOption] = Seq.empty) extends IOMessage
  245. /**
  246. * Message to an [[akka.actor.IOManager]] to create a SocketChannel connected
  247. * to the provided address with the given [[akka.actor.IO.SocketOption]]s.
  248. *
  249. * Normally sent using IOManager.connect()
  250. */
  251. case class Connect(socket: SocketHandle, address: SocketAddress, options: Seq[SocketOption] = Seq.empty) extends IOMessage
  252. /**
  253. * Message from an [[akka.actor.IOManager]] that the SocketChannel has
  254. * successfully connected.
  255. *
  256. * No action is required by the receiving [[akka.actor.Actor]].
  257. */
  258. case class Connected(socket: SocketHandle, address: SocketAddress) extends IOMessage
  259. /**
  260. * Message to an [[akka.actor.IOManager]] to close the Channel.
  261. *
  262. * Normally sent using [[akka.actor.IO.Handle]].close()
  263. */
  264. case class Close(handle: Handle) extends IOMessage
  265. /**
  266. * Message from an [[akka.actor.IOManager]] that the Channel has closed. Can
  267. * optionally contain the Exception that caused the Channel to close, if
  268. * applicable.
  269. *
  270. * No action is required by the receiving [[akka.actor.Actor]].
  271. */
  272. case class Closed(handle: Handle, cause: Input) extends IOMessage
  273. /**
  274. * Message from an [[akka.actor.IOManager]] that contains bytes read from
  275. * the SocketChannel.
  276. */
  277. case class Read(handle: ReadHandle, bytes: ByteString) extends IOMessage
  278. /**
  279. * Message to an [[akka.actor.IOManager]] to write to the SocketChannel.
  280. *
  281. * Normally sent using [[akka.actor.IO.SocketHandle]].write()
  282. */
  283. case class Write(handle: WriteHandle, bytes: ByteString) extends IOMessage
  284. /**
  285. * Represents part of a stream of bytes that can be processed by an
  286. * [[akka.actor.IO.Iteratee]].
  287. */
  288. sealed trait Input {
  289. /**
  290. * Append another Input to this one.
  291. *
  292. * If 'that' is an [[akka.actor.IO.EOF]] then it will replace any
  293. * remaining bytes in this Input. If 'this' is an [[akka.actor.IO.EOF]]
  294. * then it will be replaced by 'that'.
  295. */
  296. def ++(that: Input): Input
  297. }
  298. object Chunk {
  299. /**
  300. * Represents the empty Chunk
  301. */
  302. val empty: Chunk = new Chunk(ByteString.empty)
  303. }
  304. /**
  305. * Part of an [[akka.actor.IO.Input]] stream that contains a chunk of bytes.
  306. */
  307. case class Chunk(bytes: ByteString) extends Input {
  308. final override def ++(that: Input): Input = that match {
  309. case c @ Chunk(more)
  310. if (more.isEmpty) this
  311. else if (bytes.isEmpty) c
  312. else Chunk(bytes ++ more)
  313. case other other
  314. }
  315. }
  316. /**
  317. * Part of an [[akka.actor.IO.Input]] stream that represents the end of the
  318. * stream.
  319. *
  320. * This will cause the [[akka.actor.IO.Iteratee]] that processes it
  321. * to terminate early.
  322. */
  323. case object EOF extends Input { final override def ++(that: Input): Input = that }
  324. /**
  325. * Part of an [[akka.actor.IO.Input]] stream that represents an error in the stream.
  326. *
  327. * This will cause the [[akka.actor.IO.Iteratee]] that processes it
  328. * to terminate early.
  329. */
  330. case class Error(cause: Throwable) extends Input { final override def ++(that: Input): Input = that }
  331. object Iteratee {
  332. /**
  333. * Wrap the provided value within a [[akka.actor.IO.Done]]
  334. * [[akka.actor.IO.Iteratee]]. This is a helper for cases where the type should be
  335. * inferred as an Iteratee and not as a Done.
  336. */
  337. def apply[A](value: A): Iteratee[A] = Done(value)
  338. /**
  339. * Returns Iteratee.unit
  340. */
  341. def apply(): Iteratee[Unit] = unit
  342. /**
  343. * The single value representing Done(())
  344. */
  345. val unit: Iteratee[Unit] = Done(())
  346. }
  347. /**
  348. * A basic Iteratee implementation of Oleg's Iteratee (http://okmij.org/ftp/Streams.html).
  349. * To keep this implementation simple it has no support for Enumerator or Input types
  350. * other then ByteString.
  351. *
  352. * Other Iteratee implementations can be used in place of this one if any
  353. * missing features are required.
  354. */
  355. sealed abstract class Iteratee[+A] {
  356. /**
  357. * Processes the given [[akka.actor.IO.Input]], returning the resulting
  358. * Iteratee and the remaining Input.
  359. */
  360. final def apply(input: Input): (Iteratee[A], Input) = this match {
  361. case Next(f) f(input)
  362. case iter (iter, input)
  363. }
  364. /**
  365. * Passes an [[akka.actor.IO.EOF]] to this Iteratee and returns the
  366. * result if available.
  367. *
  368. * If this Iteratee is in a failure state then the Exception will be thrown.
  369. *
  370. * If this Iteratee is not well behaved (does not return a result on EOF)
  371. * then a "Divergent Iteratee" Exception will be thrown.
  372. */
  373. final def get: A = this(EOF)._1 match {
  374. case Done(value) value
  375. case Next(_) throw new DivergentIterateeException
  376. case Failure(t) throw t
  377. }
  378. /**
  379. * Applies a function to the result of this Iteratee, resulting in a new
  380. * Iteratee. Any unused [[akka.actor.IO.Input]] that is given to this
  381. * Iteratee will be passed to that resulting Iteratee. This is the
  382. * primary method of composing Iteratees together in order to process
  383. * an Input stream.
  384. */
  385. final def flatMap[B](f: A Iteratee[B]): Iteratee[B] = this match {
  386. case Done(value) f(value)
  387. case Next(k: Chain[_]) Next(k :+ f)
  388. case Next(k) Next(Chain(k, f))
  389. case f: Failure f
  390. }
  391. /**
  392. * Applies a function to transform the result of this Iteratee.
  393. */
  394. final def map[B](f: A B): Iteratee[B] = this match {
  395. case Done(value) Done(f(value))
  396. case Next(k: Chain[_]) Next(k :+ ((a: A) Done(f(a))))
  397. case Next(k) Next(Chain(k, (a: A) Done(f(a))))
  398. case f: Failure f
  399. }
  400. }
  401. /**
  402. * An Iteratee representing a result, usually returned by the successful
  403. * completion of an Iteratee. Also used to wrap any constants or
  404. * precalculated values that need to be composed with other Iteratees.
  405. */
  406. final case class Done[+A](result: A) extends Iteratee[A]
  407. /**
  408. * An [[akka.actor.IO.Iteratee]] that still requires more input to calculate
  409. * it's result.
  410. */
  411. final case class Next[+A](f: Input (Iteratee[A], Input)) extends Iteratee[A]
  412. /**
  413. * An [[akka.actor.IO.Iteratee]] that represents an erronous end state.
  414. */
  415. final case class Failure(cause: Throwable) extends Iteratee[Nothing]
  416. //FIXME general description of what an IterateeRef is and how it is used, potentially with link to docs
  417. object IterateeRef {
  418. /**
  419. * Creates an [[akka.actor.IO.IterateeRefSync]] containing an initial
  420. * [[akka.actor.IO.Iteratee]].
  421. */
  422. def sync[A](initial: Iteratee[A]): IterateeRefSync[A] = new IterateeRefSync(initial)
  423. /**
  424. * Creates an empty [[akka.actor.IO.IterateeRefSync]].
  425. */
  426. def sync(): IterateeRefSync[Unit] = new IterateeRefSync(Iteratee.unit)
  427. /**
  428. * Creates an [[akka.actor.IO.IterateeRefAsync]] containing an initial
  429. * [[akka.actor.IO.Iteratee]].
  430. */
  431. def async[A](initial: Iteratee[A])(implicit executor: ExecutionContext): IterateeRefAsync[A] = new IterateeRefAsync(initial)
  432. /**
  433. * Creates an empty [[akka.actor.IO.IterateeRefAsync]].
  434. */
  435. def async()(implicit executor: ExecutionContext): IterateeRefAsync[Unit] = new IterateeRefAsync(Iteratee.unit)
  436. /**
  437. * A mutable Map to contain multiple IterateeRefs.
  438. *
  439. * This Map differs from the mutable Map within Scala's standard library
  440. * by automatically including any keys used to lookup an IterateeRef. The
  441. * 'refFactory' is used to provide the default value for new keys.
  442. */
  443. class Map[K, V] private (refFactory: IterateeRef[V], underlying: mutable.Map[K, IterateeRef[V]] = mutable.Map.empty[K, IterateeRef[V]]) extends mutable.Map[K, IterateeRef[V]] {
  444. override def get(key: K) = Some(underlying.getOrElseUpdate(key, refFactory))
  445. override def iterator = underlying.iterator
  446. override def +=(kv: (K, IterateeRef[V])) = { underlying += kv; this }
  447. override def -=(key: K) = { underlying -= key; this }
  448. override def empty = new Map[K, V](refFactory)
  449. }
  450. //FIXME general description of what an Map is and how it is used, potentially with link to docs
  451. object Map {
  452. /**
  453. * Uses a factory to create the initial IterateeRef for each new key.
  454. */
  455. def apply[K, V](refFactory: IterateeRef[V]): IterateeRef.Map[K, V] = new Map(refFactory)
  456. /**
  457. * Creates an empty [[akka.actor.IO.IterateeRefSync]] for each new key.
  458. */
  459. def sync[K](): IterateeRef.Map[K, Unit] = new Map(IterateeRef.sync())
  460. /**
  461. * Creates an empty [[akka.actor.IO.IterateeRefAsync]] for each new key.
  462. */
  463. def async[K]()(implicit executor: ExecutionContext): IterateeRef.Map[K, Unit] = new Map(IterateeRef.async())
  464. }
  465. }
  466. /**
  467. * A mutable reference to an Iteratee designed for use within an Actor.
  468. *
  469. * See [[akka.actor.IO.IterateeRefSync]] and [[akka.actor.IO.IterateeRefAsync]]
  470. * for details.
  471. */
  472. trait IterateeRef[A] {
  473. //FIXME Add docs
  474. def flatMap(f: A Iteratee[A]): Unit
  475. //FIXME Add docs
  476. def map(f: A A): Unit
  477. //FIXME Add docs
  478. def apply(input: Input): Unit
  479. }
  480. /**
  481. * A mutable reference to an [[akka.actor.IO.Iteratee]]. Not thread safe.
  482. *
  483. * Designed for use within an [[akka.actor.Actor]].
  484. *
  485. * Includes mutable implementations of flatMap, map, and apply which
  486. * update the internal reference and return Unit.
  487. *
  488. * [[akka.actor.IO.Input]] remaining after processing the Iteratee will
  489. * be stored and processed later when 'flatMap' is used next.
  490. */
  491. final class IterateeRefSync[A](initial: Iteratee[A]) extends IterateeRef[A] {
  492. private var _value: (Iteratee[A], Input) = (initial, Chunk.empty)
  493. override def flatMap(f: A Iteratee[A]): Unit = _value = _value match {
  494. case (iter, chunk @ Chunk(bytes)) if bytes.nonEmpty (iter flatMap f)(chunk)
  495. case (iter, input) (iter flatMap f, input)
  496. }
  497. override def map(f: A A): Unit = _value = (_value._1 map f, _value._2)
  498. override def apply(input: Input): Unit = _value = _value._1(_value._2 ++ input)
  499. /**
  500. * Returns the current value of this IterateeRefSync
  501. */
  502. def value: (Iteratee[A], Input) = _value
  503. }
  504. /**
  505. * A mutable reference to an [[akka.actor.IO.Iteratee]]. Not thread safe.
  506. *
  507. * Designed for use within an [[akka.actor.Actor]], although all actions
  508. * perfomed on the Iteratee are processed within a [[scala.concurrent.Future]]
  509. * so it is not safe to refer to the Actor's state from within this Iteratee.
  510. * Messages should instead be sent to the Actor in order to modify state.
  511. *
  512. * Includes mutable implementations of flatMap, map, and apply which
  513. * update the internal reference and return Unit.
  514. *
  515. * [[akka.actor.IO.Input]] remaining after processing the Iteratee will
  516. * be stored and processed later when 'flatMap' is used next.
  517. */
  518. final class IterateeRefAsync[A](initial: Iteratee[A])(implicit executor: ExecutionContext) extends IterateeRef[A] {
  519. private var _value: Future[(Iteratee[A], Input)] = Future((initial, Chunk.empty))
  520. override def flatMap(f: A Iteratee[A]): Unit = _value = _value map {
  521. case (iter, chunk @ Chunk(bytes)) if bytes.nonEmpty (iter flatMap f)(chunk)
  522. case (iter, input) (iter flatMap f, input)
  523. }
  524. override def map(f: A A): Unit = _value = _value map (v (v._1 map f, v._2))
  525. override def apply(input: Input): Unit = _value = _value map (v v._1(v._2 ++ input))
  526. /**
  527. * Returns a Future which will hold the future value of this IterateeRefAsync
  528. */
  529. def future: Future[(Iteratee[A], Input)] = _value
  530. }
  531. /**
  532. * An Iteratee that returns the ByteString prefix up until the supplied delimiter.
  533. * The delimiter is dropped by default, but it can be returned with the result by
  534. * setting 'inclusive' to be 'true'.
  535. */
  536. def takeUntil(delimiter: ByteString, inclusive: Boolean = false): Iteratee[ByteString] = {
  537. def step(taken: ByteString)(input: Input): (Iteratee[ByteString], Input) = input match {
  538. case Chunk(more)
  539. val bytes = taken ++ more
  540. val startIdx = bytes.indexOfSlice(delimiter, math.max(taken.length - delimiter.length, 0))
  541. if (startIdx >= 0) {
  542. val endIdx = startIdx + delimiter.length
  543. (Done(bytes take (if (inclusive) endIdx else startIdx)), Chunk(bytes drop endIdx))
  544. } else {
  545. (Next(step(bytes)), Chunk.empty)
  546. }
  547. case EOF (Failure(new EOFException("Unexpected EOF")), EOF)
  548. case e @ Error(cause) (Failure(cause), e)
  549. }
  550. Next(step(ByteString.empty))
  551. }
  552. /**
  553. * An Iteratee that will collect bytes as long as a predicate is true.
  554. */
  555. def takeWhile(p: (Byte) Boolean): Iteratee[ByteString] = {
  556. def step(taken: ByteString)(input: Input): (Iteratee[ByteString], Input) = input match {
  557. case Chunk(more)
  558. val (found, rest) = more span p
  559. if (rest.isEmpty)
  560. (Next(step(taken ++ found)), Chunk.empty)
  561. else
  562. (Done(taken ++ found), Chunk(rest))
  563. case EOF (Failure(new EOFException("Unexpected EOF")), EOF)
  564. case e @ Error(cause) (Failure(cause), e)
  565. }
  566. Next(step(ByteString.empty))
  567. }
  568. /**
  569. * An Iteratee that returns a ByteString of the requested length.
  570. */
  571. def take(length: Int): Iteratee[ByteString] = {
  572. def step(taken: ByteString)(input: Input): (Iteratee[ByteString], Input) = input match {
  573. case Chunk(more)
  574. val bytes = taken ++ more
  575. if (bytes.length >= length)
  576. (Done(bytes.take(length)), Chunk(bytes.drop(length)))
  577. else
  578. (Next(step(bytes)), Chunk.empty)
  579. case EOF (Failure(new EOFException("Unexpected EOF")), EOF)
  580. case e @ Error(cause) (Failure(cause), e)
  581. }
  582. Next(step(ByteString.empty))
  583. }
  584. /**
  585. * An Iteratee that ignores the specified number of bytes.
  586. */
  587. def drop(length: Int): Iteratee[Unit] = {
  588. def step(left: Int)(input: Input): (Iteratee[Unit], Input) = input match {
  589. case Chunk(more)
  590. if (left > more.length)
  591. (Next(step(left - more.length)), Chunk.empty)
  592. else
  593. (Done(()), Chunk(more drop left))
  594. case EOF (Failure(new EOFException("Unexpected EOF")), EOF)
  595. case e @ Error(cause) (Failure(cause), e)
  596. }
  597. Next(step(length))
  598. }
  599. /**
  600. * An Iteratee that returns the remaining ByteString until an EOF is given.
  601. */
  602. val takeAll: Iteratee[ByteString] = {
  603. def step(taken: ByteString)(input: Input): (Iteratee[ByteString], Input) = input match {
  604. case Chunk(more)
  605. val bytes = taken ++ more
  606. (Next(step(bytes)), Chunk.empty)
  607. case EOF (Done(taken), EOF)
  608. case e @ Error(cause) (Failure(cause), e)
  609. }
  610. Next(step(ByteString.empty))
  611. }
  612. /**
  613. * An Iteratee that returns any input it receives
  614. */
  615. val takeAny: Iteratee[ByteString] = Next {
  616. case Chunk(bytes) if bytes.nonEmpty (Done(bytes), Chunk.empty)
  617. case Chunk(bytes) (takeAny, Chunk.empty)
  618. case EOF (Done(ByteString.empty), EOF)
  619. case e @ Error(cause) (Failure(cause), e)
  620. }
  621. /**
  622. * An Iteratee that creates a list made up of the results of an Iteratee.
  623. */
  624. def takeList[A](length: Int)(iter: Iteratee[A]): Iteratee[List[A]] = {
  625. def step(left: Int, list: List[A]): Iteratee[List[A]] =
  626. if (left == 0) Done(list.reverse)
  627. else iter flatMap (a step(left - 1, a :: list))
  628. step(length, Nil)
  629. }
  630. /**
  631. * An Iteratee that returns a [[akka.util.ByteString]] of the request length,
  632. * but does not consume the Input.
  633. */
  634. def peek(length: Int): Iteratee[ByteString] = {
  635. def step(taken: ByteString)(input: Input): (Iteratee[ByteString], Input) = input match {
  636. case Chunk(more)
  637. val bytes = taken ++ more
  638. if (bytes.length >= length)
  639. (Done(bytes.take(length)), Chunk(bytes))
  640. else
  641. (Next(step(bytes)), Chunk.empty)
  642. case EOF (Done(taken), EOF)
  643. case e @ Error(cause) (Failure(cause), e)
  644. }
  645. Next(step(ByteString.empty))
  646. }
  647. /**
  648. * An Iteratee that continually repeats an Iteratee.
  649. */
  650. def repeat[T](iter: Iteratee[T]): Iteratee[T] = iter flatMap (_ repeat(iter))
  651. /**
  652. * An Iteratee that applies an Iteratee to each element of a Traversable
  653. * and finally returning a single Iteratee containing a Traversable of the results.
  654. */
  655. def traverse[A, B, M[A] <: Traversable[A]](in: M[A])(f: A Iteratee[B])(implicit cbf: CanBuildFrom[M[A], B, M[B]]): Iteratee[M[B]] =
  656. fold(cbf(in), in)((b, a) f(a) map (b += _)) map (_.result)
  657. /**
  658. * An Iteratee that folds over a Traversable by applying a function that
  659. * returns an Iteratee.
  660. */
  661. def fold[A, B, M[A] <: Traversable[A]](initial: B, in: M[A])(f: (B, A) Iteratee[B]): Iteratee[B] =
  662. (Iteratee(initial) /: in)((ib, a) ib flatMap (b f(b, a)))
  663. // private api
  664. private object Chain {
  665. def apply[A](f: Input (Iteratee[A], Input)) = new Chain[A](f, Nil, Nil)
  666. def apply[A, B](f: Input (Iteratee[A], Input), k: A Iteratee[B]) = new Chain[B](f, List(k.asInstanceOf[Any Iteratee[Any]]), Nil)
  667. }
  668. /**
  669. * A function 'ByteString => Iteratee[A]' that composes with 'A => Iteratee[B]' functions
  670. * in a stack-friendly manner.
  671. *
  672. * For internal use within Iteratee.
  673. */
  674. private final case class Chain[A] private (cur: Input (Iteratee[Any], Input), queueOut: List[Any Iteratee[Any]], queueIn: List[Any Iteratee[Any]]) extends (Input (Iteratee[A], Input)) {
  675. def :+[B](f: A Iteratee[B]) = new Chain[B](cur, queueOut, f.asInstanceOf[Any Iteratee[Any]] :: queueIn)
  676. def apply(input: Input): (Iteratee[A], Input) = {
  677. @tailrec
  678. def run(result: (Iteratee[Any], Input), queueOut: List[Any Iteratee[Any]], queueIn: List[Any Iteratee[Any]]): (Iteratee[Any], Input) = {
  679. if (queueOut.isEmpty) {
  680. if (queueIn.isEmpty) result
  681. else run(result, queueIn.reverse, Nil)
  682. } else result match {
  683. case (Done(value), rest)
  684. queueOut.head(value) match {
  685. case Next(f) run(f(rest), queueOut.tail, queueIn)
  686. case iter run((iter, rest), queueOut.tail, queueIn)
  687. }
  688. case (Next(f), rest) (Next(new Chain(f, queueOut, queueIn)), rest)
  689. case _ result
  690. }
  691. }
  692. run(cur(input), queueOut, queueIn).asInstanceOf[(Iteratee[A], Input)]
  693. }
  694. }
  695. }
  696. /**
  697. * IOManager contains a reference to the [[akka.actor.IOManagerActor]] for
  698. * an [[akka.actor.ActorSystem]].
  699. *
  700. * This is the recommended entry point to creating sockets for performing
  701. * IO.
  702. *
  703. * Use the companion object to retrieve the instance of this class for an
  704. * ActorSystem.
  705. *
  706. * {{{
  707. * val ioManager = IOManager(context.system)
  708. * val socket = ioManager.connect("127.0.0.1")
  709. * }}}
  710. *
  711. * An IOManager does not need to be manually stopped when not in use as it will
  712. * automatically enter an idle state when it has no channels to manage.
  713. */
  714. final class IOManager private (system: ExtendedActorSystem) extends Extension { //FIXME how about taking an ActorNextext
  715. val settings: Settings = {
  716. val c = system.settings.config.getConfig("akka.io")
  717. Settings(
  718. readBufferSize = {
  719. val sz = c.getBytes("read-buffer-size")
  720. require(sz <= Int.MaxValue && sz > 0)
  721. sz.toInt
  722. },
  723. selectInterval = c.getInt("select-interval"),
  724. defaultBacklog = c.getInt("default-backlog"))
  725. }
  726. /**
  727. * A reference to the [[akka.actor.IOManagerActor]] that performs the actual
  728. * IO. It communicates with other actors using subclasses of
  729. * [[akka.actor.IO.IOMessage]].
  730. */
  731. val actor: ActorRef = system.actorOf(Props(new IOManagerActor(settings)), "io-manager")
  732. /**
  733. * Create a ServerSocketChannel listening on an address. Messages will be
  734. * sent from the [[akka.actor.IOManagerActor]] to the owner
  735. * [[akka.actor.ActorRef]].
  736. *
  737. * @param address the address to listen on
  738. * @param owner the ActorRef that will receive messages from the IOManagerActor
  739. * @param option Seq of [[akka.actor.IO.ServerSocketOptions]] to setup on socket
  740. * @return a [[akka.actor.IO.ServerHandle]] to uniquely identify the created socket
  741. */
  742. def listen(address: SocketAddress, options: Seq[IO.ServerSocketOption])(implicit owner: ActorRef): IO.ServerHandle = {
  743. val server = IO.ServerHandle(owner, actor)
  744. actor ! IO.Listen(server, address, options)
  745. server
  746. }
  747. /**
  748. * Create a ServerSocketChannel listening on an address. Messages will be
  749. * sent from the [[akka.actor.IOManagerActor]] to the owner
  750. * [[akka.actor.ActorRef]].
  751. *
  752. * @param address the address to listen on
  753. * @param owner the ActorRef that will receive messages from the IOManagerActor
  754. * @return a [[akka.actor.IO.ServerHandle]] to uniquely identify the created socket
  755. */
  756. def listen(address: SocketAddress)(implicit owner: ActorRef): IO.ServerHandle = listen(address, Seq.empty)
  757. /**
  758. * Create a ServerSocketChannel listening on a host and port. Messages will
  759. * be sent from the [[akka.actor.IOManagerActor]] to the owner
  760. * [[akka.actor.ActorRef]].
  761. *
  762. * @param host the hostname or IP to listen on
  763. * @param port the port to listen on
  764. * @param options Seq of [[akka.actor.IO.ServerSocketOption]] to setup on socket
  765. * @param owner the ActorRef that will receive messages from the IOManagerActor
  766. * @return a [[akka.actor.IO.ServerHandle]] to uniquely identify the created socket
  767. */
  768. def listen(host: String, port: Int, options: Seq[IO.ServerSocketOption] = Seq.empty)(implicit owner: ActorRef): IO.ServerHandle =
  769. listen(new InetSocketAddress(host, port), options)(owner)
  770. /**
  771. * Create a SocketChannel connecting to an address. Messages will be
  772. * sent from the [[akka.actor.IOManagerActor]] to the owner
  773. * [[akka.actor.ActorRef]].
  774. *
  775. * @param address the address to connect to
  776. * @param options Seq of [[akka.actor.IO.SocketOption]] to setup on established socket
  777. * @param owner the ActorRef that will receive messages from the IOManagerActor
  778. * @return a [[akka.actor.IO.SocketHandle]] to uniquely identify the created socket
  779. */
  780. def connect(address: SocketAddress, options: Seq[IO.SocketOption] = Seq.empty)(implicit owner: ActorRef): IO.SocketHandle = {
  781. val socket = IO.SocketHandle(owner, actor)
  782. actor ! IO.Connect(socket, address, options)
  783. socket
  784. }
  785. /**
  786. * Create a SocketChannel connecting to a host and port. Messages will
  787. * be sent from the [[akka.actor.IOManagerActor]] to the owner
  788. * [[akka.actor.ActorRef]].
  789. *
  790. * @param host the hostname or IP to connect to
  791. * @param port the port to connect to
  792. * @param options Seq of [[akka.actor.IO.SocketOption]] to setup on established socket
  793. * @param owner the ActorRef that will receive messages from the IOManagerActor
  794. * @return a [[akka.actor.IO.SocketHandle]] to uniquely identify the created socket
  795. */
  796. def connect(host: String, port: Int)(implicit owner: ActorRef): IO.SocketHandle =
  797. connect(new InetSocketAddress(host, port))(owner)
  798. }
  799. //FIXME add docs
  800. object IOManager extends ExtensionId[IOManager] with ExtensionIdProvider {
  801. override def lookup: IOManager.type = this
  802. override def createExtension(system: ExtendedActorSystem): IOManager = new IOManager(system)
  803. @SerialVersionUID(1L)
  804. case class Settings(readBufferSize: Int, selectInterval: Int, defaultBacklog: Int) {
  805. require(readBufferSize <= Int.MaxValue && readBufferSize > 0)
  806. require(selectInterval > 0)
  807. }
  808. }
  809. /**
  810. * An [[akka.actor.Actor]] that performs IO using a Java NIO Selector.
  811. *
  812. * Use [[akka.actor.IOManager]] to retrieve an instance of this Actor.
  813. */
  814. final class IOManagerActor(val settings: Settings) extends Actor with ActorLogging {
  815. import SelectionKey.{ OP_READ, OP_WRITE, OP_ACCEPT, OP_CONNECT }
  816. import settings.{ defaultBacklog, selectInterval, readBufferSize }
  817. private type ReadChannel = ReadableByteChannel with SelectableChannel
  818. private type WriteChannel = WritableByteChannel with SelectableChannel
  819. private val selector: Selector = Selector open ()
  820. private val channels = mutable.Map.empty[IO.Handle, SelectableChannel]
  821. private val accepted = mutable.Map.empty[IO.ServerHandle, mutable.Queue[SelectableChannel]]
  822. private val writes = mutable.Map.empty[IO.WriteHandle, WriteBuffer]
  823. /** Channels that should close after writes are complete */
  824. private val closing = mutable.Set.empty[IO.Handle]
  825. /** Buffer used for all reads */
  826. private val buffer = ByteBuffer.allocate(readBufferSize)
  827. /** a counter that is incremented each time a message is retrieved */
  828. private var lastSelect = 0
  829. /** true while the selector is open and channels.nonEmpty */
  830. private var running = false
  831. /** is there already a Select message in flight? */
  832. private var selectSent = false
  833. /**
  834. * select blocks for 1ms when false and is completely nonblocking when true.
  835. * Automatically changes due to activity. This reduces object allocations
  836. * when there are no pending events.
  837. */
  838. private var fastSelect = false
  839. /** unique message that is sent to ourself to initiate the next select */
  840. private case object Select
  841. /** This method should be called after receiving any message */
  842. private def run() {
  843. if (!running) {
  844. running = true
  845. if (!selectSent) {
  846. selectSent = true
  847. self ! Select
  848. }
  849. }
  850. lastSelect += 1
  851. if (lastSelect >= selectInterval)
  852. running = select()
  853. }
  854. /**
  855. * @return true if we should be running and false if not
  856. */
  857. private def select(): Boolean = try {
  858. if (selector.isOpen) {
  859. // TODO: Make select behaviour configurable.
  860. // Blocking 1ms reduces allocations during idle times, non blocking gives better performance.
  861. if (fastSelect) selector.selectNow else selector.select(1)
  862. val keys = selector.selectedKeys.iterator
  863. fastSelect = keys.hasNext
  864. while (keys.hasNext) {
  865. val key = keys.next()
  866. keys.remove()
  867. if (key.isValid) process(key)
  868. }
  869. if (channels.isEmpty) false else running
  870. } else {
  871. false
  872. }
  873. } finally {
  874. lastSelect = 0
  875. }
  876. private def forwardFailure(f: Unit): Unit = try f catch { case NonFatal(e) sender ! Status.Failure(e) }
  877. private def setSocketOptions(socket: java.net.Socket, options: Seq[IO.SocketOption]) {
  878. options foreach {
  879. case IO.KeepAlive(on) forwardFailure(socket.setKeepAlive(on))
  880. case IO.OOBInline(on) forwardFailure(socket.setOOBInline(on))
  881. case IO.ReceiveBufferSize(size) forwardFailure(socket.setReceiveBufferSize(size))
  882. case IO.ReuseAddress(on) forwardFailure(socket.setReuseAddress(on))
  883. case IO.SendBufferSize(size) forwardFailure(socket.setSendBufferSize(size))
  884. case IO.SoLinger(linger) forwardFailure(socket.setSoLinger(linger.isDefined, math.max(0, linger.getOrElse(socket.getSoLinger))))
  885. case IO.SoTimeout(timeout) forwardFailure(socket.setSoTimeout(timeout.toMillis.toInt))
  886. case IO.TcpNoDelay(on) forwardFailure(socket.setTcpNoDelay(on))
  887. case IO.TrafficClass(tc) forwardFailure(socket.setTrafficClass(tc))
  888. case IO.PerformancePreferences(connTime, latency, bandwidth)
  889. forwardFailure(socket.setPerformancePreferences(connTime, latency, bandwidth))
  890. }
  891. }
  892. def receive = {
  893. case Select
  894. running = select()
  895. if (running) self ! Select
  896. selectSent = running
  897. case IO.Listen(server, address, options)
  898. val channel = ServerSocketChannel open ()
  899. channel configureBlocking false
  900. var backlog = defaultBacklog
  901. val sock = channel.socket
  902. options foreach {
  903. case IO.ReceiveBufferSize(size) forwardFailure(sock.setReceiveBufferSize(size))
  904. case IO.ReuseAddress(on) forwardFailure(sock.setReuseAddress(on))
  905. case IO.PerformancePreferences(connTime, latency, bandwidth)
  906. forwardFailure(sock.setPerformancePreferences(connTime, latency, bandwidth))
  907. case IO.Backlog(number) backlog = number
  908. }
  909. channel.socket bind (address, backlog)
  910. channels update (server, channel)
  911. channel register (selector, OP_ACCEPT, server)
  912. server.owner ! IO.Listening(server, sock.getLocalSocketAddress())
  913. run()
  914. case IO.Connect(socket, address, options)
  915. val channel = SocketChannel open ()
  916. channel configureBlocking false
  917. channel connect address
  918. setSocketOptions(channel.socket, options)
  919. channels update (socket, channel)
  920. channel register (selector, OP_CONNECT | OP_READ, socket)
  921. run()
  922. case IO.Accept(socket, server, options)
  923. val queue = accepted(server)
  924. val channel = queue.dequeue()
  925. channel match { case socketChannel: SocketChannel setSocketOptions(socketChannel.socket, options) }
  926. channels update (socket, channel)
  927. channel register (selector, OP_READ, socket)
  928. run()
  929. case IO.Write(handle, data)
  930. if (channels contains handle) {
  931. val queue = writes get handle getOrElse {
  932. val q = new WriteBuffer(readBufferSize)
  933. writes update (handle, q)
  934. q
  935. }
  936. if (queue.isEmpty) addOps(handle, OP_WRITE)
  937. queue enqueue data
  938. if (queue.length >= readBufferSize) write(handle, channels(handle).asInstanceOf[WriteChannel])
  939. }
  940. run()
  941. case IO.Close(handle: IO.WriteHandle)
  942. //If we still have pending writes, add to set of closing handles
  943. if (writes get handle exists (_.isEmpty == false)) closing += handle
  944. else cleanup(handle, IO.EOF)
  945. run()
  946. case IO.Close(handle)
  947. cleanup(handle, IO.EOF)
  948. run()
  949. }
  950. override def postStop {
  951. channels.keys foreach (handle cleanup(handle, IO.EOF))
  952. selector.close
  953. }
  954. private def process(key: SelectionKey) {
  955. val handle = key.attachment.asInstanceOf[IO.Handle]
  956. try {
  957. if (key.isConnectable) key.channel match { case channel: SocketChannel connect(handle.asSocket, channel) }
  958. if (key.isAcceptable) key.channel match { case channel: ServerSocketChannel accept(handle.asServer, channel) }
  959. if (key.isReadable) key.channel match { case channel: ReadChannel read(handle.asReadable, channel) }
  960. if (key.isWritable) key.channel match { case channel: WriteChannel try write(handle.asWritable, channel) catch { case e: IOException } } // ignore, let it fail on read to ensure nothing left in read buffer.
  961. } catch {
  962. case e @ (_: ClassCastException | _: CancelledKeyException | _: IOException | _: ActorInitializationException)
  963. cleanup(handle, IO.Error(e)) //Scala patmat is broken
  964. }
  965. }
  966. private def cleanup(handle: IO.Handle, cause: IO.Input) {
  967. closing -= handle
  968. handle match {
  969. case server: IO.ServerHandle accepted -= server
  970. case writable: IO.WriteHandle writes -= writable
  971. }
  972. channels.get(handle) foreach {
  973. channel
  974. try channel.close finally {
  975. channels -= handle
  976. if (!handle.owner.isTerminated) handle.owner ! IO.Closed(handle, cause)
  977. }
  978. }
  979. }
  980. private def addOps(handle: IO.Handle, ops: Int) {
  981. val key = channels(handle) keyFor selector
  982. val cur = key.interestOps
  983. key interestOps (cur | ops)
  984. }
  985. private def removeOps(handle: IO.Handle, ops: Int) {
  986. val key = channels(handle) keyFor selector
  987. val cur = key.interestOps
  988. key interestOps (cur - (cur & ops))
  989. }
  990. private def connect(socket: IO.SocketHandle, channel: SocketChannel) {
  991. if (channel.finishConnect) {
  992. removeOps(socket, OP_CONNECT)
  993. socket.owner ! IO.Connected(socket, channel.socket.getRemoteSocketAddress())
  994. } else {
  995. cleanup(socket, IO.Error(new IllegalStateException("Channel for socket handle [%s] didn't finish connect" format socket)))
  996. }
  997. }
  998. @tailrec
  999. private def accept(server: IO.ServerHandle, channel: ServerSocketChannel) {
  1000. val socket = channel.accept
  1001. if (socket ne null) {
  1002. socket configureBlocking false
  1003. val queue = {
  1004. val existing = accepted get server
  1005. if (existing.isDefined) existing.get
  1006. else {
  1007. val q = mutable.Queue[SelectableChannel]()
  1008. accepted update (server, q)
  1009. q
  1010. }
  1011. }
  1012. queue += socket
  1013. server.owner ! IO.NewClient(server)
  1014. accept(server, channel)
  1015. }
  1016. }
  1017. @tailrec
  1018. private def read(handle: IO.ReadHandle, channel: ReadChannel) {
  1019. buffer.clear
  1020. val readLen = channel read buffer
  1021. if (readLen == -1) {
  1022. cleanup(handle, IO.EOF)
  1023. } else if (readLen > 0) {
  1024. buffer.flip
  1025. handle.owner ! IO.Read(handle, ByteString(buffer))
  1026. if (readLen == buffer.capacity) read(handle, channel)
  1027. }
  1028. }
  1029. private def write(handle: IO.WriteHandle, channel: WriteChannel) {
  1030. val queue = writes(handle)
  1031. queue write channel
  1032. if (queue.isEmpty) {
  1033. if (closing(handle)) cleanup(handle, IO.EOF)
  1034. else removeOps(handle, OP_WRITE)
  1035. }
  1036. }
  1037. }
  1038. //FIXME is this public API?
  1039. final class WriteBuffer(bufferSize: Int) {
  1040. private val _queue = new java.util.ArrayDeque[ByteString]
  1041. private val _buffer = ByteBuffer.allocate(bufferSize)
  1042. private var _length = 0
  1043. private def fillBuffer(): Boolean = {
  1044. while (!_queue.isEmpty && _buffer.hasRemaining) {
  1045. val next = _queue.pollFirst
  1046. val rest = next.drop(next.copyToBuffer(_buffer))
  1047. if (rest.nonEmpty) _queue.offerFirst(rest)
  1048. }
  1049. !_buffer.hasRemaining
  1050. }
  1051. def enqueue(elem: ByteString): this.type = {
  1052. _length += elem.length
  1053. val rest = elem.drop(elem.copyToBuffer(_buffer))
  1054. if (rest.nonEmpty) _queue.offerLast(rest)
  1055. this
  1056. }
  1057. def length: Int = _length
  1058. def isEmpty: Boolean = _length == 0
  1059. def write(channel: WritableByteChannel with SelectableChannel): Int = {
  1060. @tailrec
  1061. def run(total: Int): Int = {
  1062. if (this.isEmpty) total
  1063. else {
  1064. val written = try {
  1065. _buffer.flip()
  1066. channel write _buffer
  1067. } finally {
  1068. // don't leave buffer in wrong state
  1069. _buffer.compact()
  1070. fillBuffer()
  1071. }
  1072. _length -= written
  1073. if (_buffer.position > 0) {
  1074. total + written
  1075. } else {
  1076. run(total + written)
  1077. }
  1078. }
  1079. }
  1080. run(0)
  1081. }
  1082. }