Search code examples
scalamemoryrecursionstack-overflow

Twitter's "effective scala" broker example and tail recursion


In the document "Effective Scala" published by twitter, I see a code example:

class Pool(conns: Seq[Conn]) {
  private[this] val waiters = new Broker[Conn]
  private[this] val returnConn = new Broker[Conn]

  val get: Offer[Conn] = waiters.recv
  def put(c: Conn) { returnConn ! c }

  private[this] def loop(connq: Queue[Conn]) {
    Offer.choose(
      if (connq.isEmpty) Offer.never else {
        val (head, rest) = connq.dequeue
        waiters.send(head) { _ => loop(rest) }
      },
      returnConn.recv { c => loop(connq enqueue c) }
    ).sync()
  }

  loop(Queue.empty ++ conns)
}

The code doesn't appear to be tail recursive, and isn't annotated as such. Since this is a connection pool that would presumably be left running for the life of the program, what would prevent a pool like this from eventually blowing up the stack, and generating a StackOverflowException?


Solution

  • The code is not recursive at all! loop does not call itself. It passes closures { _ => loop(rest) } and { c => loop(connq enqueue c) } to waiters.send and returnConn.recv respectively which call loop again. No recursion hence no stack overflow.