Skip to content

Instantly share code, notes, and snippets.

@theanti9
Created July 31, 2014 06:51
Show Gist options
  • Select an option

  • Save theanti9/90550cfb872d64a5b4dd to your computer and use it in GitHub Desktop.

Select an option

Save theanti9/90550cfb872d64a5b4dd to your computer and use it in GitHub Desktop.

Revisions

  1. theanti9 created this gist Jul 31, 2014.
    44 changes: 44 additions & 0 deletions ConnectionPool.scala
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,44 @@
    import java.util.concurrent.BlockingQueue
    import java.util.concurrent.LinkedBlockingQueue
    import java.util.concurrent.TimeUnit

    class MaxLeaseRetriesException(message:String = null, cause:Throwable = null) extends Exception(message, cause)

    class ConnectionPool[R](maxSize:Int, timeout:Int = 1000, unit: TimeUnit = TimeUnit.MILLISECONDS) {

    val q: BlockingQueue[R] = new LinkedBlockingQueue[R](maxSize)

    /**
    * Given an initialization block, fill the connection pool.
    */
    def construct(block: ()=> R) {
    for (_ <- 0 to maxSize) {
    q.put(block())
    }
    }

    /**
    * Lease a connection from the pool for the duration of a code block
    * Use the default timeout to try and acquire the lease. Retry `maxRetries` times
    * to acquire the lease.
    *
    * Throws a MaxLeaseRetriesException if the maxRetries is hit with no luck.
    */
    def lease[T](block: R => T, maxRetries:Int=10): T = {
    var con:R = q.poll(timeout, unit)
    var tries:Int = 1

    while (con == null && tries <= maxRetries) {
    con = q.poll(timeout, unit)
    tries+=1
    }

    if (con == null) {
    throw new MaxLeaseRetriesException(s"Tried to acquire connection lease ${maxRetries} times with no success!")
    }

    val result = block(con)
    q.put(con)
    result
    }
    }