Last active
December 27, 2015 17:39
-
-
Save agleyzer/7363353 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.twitter.conversions.time._ | |
import com.twitter.finagle.{Addr, Name} | |
import com.twitter.finagle.util.DefaultTimer | |
import com.twitter.logging.Logger | |
import com.twitter.util.{Duration, Future, FuturePool, Timer, Updatable, Var} | |
import java.net.{InetAddress, InetSocketAddress, SocketAddress} | |
import java.security.Security | |
/** | |
* A name that continuously resolves itself with DNS. | |
*/ | |
private[util] trait DnsBackedName extends Name { | |
private[this] val log = Logger(this.getClass) | |
private[this] val addrVar = Var[Addr](Addr.Pending) | |
protected def host: String | |
protected def ttl: Duration | |
protected def timer: Timer | |
protected def resolveHost: Future[Set[SocketAddress]] | |
override val bind = addrVar | |
protected[util] def loop(currentSet: Set[SocketAddress] = Set.empty): Unit = { | |
resolveHost handle { case ex => | |
log.error("failed to resolve host: " + ex) | |
addrVar() = Addr.Failed(ex) | |
Set[SocketAddress]() | |
} onSuccess { newSet => | |
if (currentSet != newSet) { | |
log.debug("%s is now: %s", host, newSet.mkString(", ")) | |
addrVar() = Addr.Bound(newSet.toSeq:_*) | |
} | |
timer.doLater(ttl) { loop(newSet) } | |
} | |
} | |
} | |
private[util] class BlockingDnsBackedName(val host: String, val port: Int, | |
val ttl: Duration, val timer: Timer) extends DnsBackedName { | |
private[this] def blockingDnsCall: Set[SocketAddress] = | |
InetAddress.getAllByName(host).map { address => | |
new InetSocketAddress(address, port): SocketAddress | |
}.toSet | |
protected def resolveHost: Future[Set[SocketAddress]] = | |
FuturePool.unboundedPool(blockingDnsCall) | |
loop() | |
} | |
object DnsBackedName { | |
def apply(host: String, port: Int, ttl: Duration): Name = | |
new BlockingDnsBackedName(host, port, ttl, DefaultTimer.twitter) | |
def apply(host: String, port: Int): Name = { | |
// TTL using Java standard secutity property | |
val ttl = { | |
val minTtl = 5.seconds | |
val defaultTtl = 10.seconds | |
val maxTtl = 1.hour | |
val property = Option(Security.getProperty("networkaddress.cache.ttl")) | |
property map (_.toInt.seconds max minTtl min maxTtl) getOrElse defaultTtl | |
} | |
apply(host, port, ttl) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment