im.yagni.common.Wait.scala Maven / Gradle / Ivy
The newest version!
package im.yagni.common
import scala.annotation.tailrec
object Wait {
//TODO: rename all to millis
def waitUpTo(millis: Long = Timeout.default) = new Wait(millis)
}
private[yagni] class Wait(millis: Long) {
def forCondition(f: => Boolean, desc: => String, onFail: () => Unit = () => ()) {
if (!conditionSatisfied(f)) {
onFail()
throw new ConditionNotMetException("> FAILED: " + desc, millis)
}
}
private def conditionSatisfied[T](f: => Boolean): Boolean = {
val end = System.currentTimeMillis() + millis
def tryIt = try {f} catch {case _ => false}
def timedOut = System.currentTimeMillis() >= end
@tailrec
def loop(last: Boolean): Boolean = {
if (last || timedOut) last
else {
Thread.sleep(100)
loop(tryIt)
}
}
loop(tryIt)
}
}
class ConditionNotMetException(message: String) extends RuntimeException(message) {
def this(conditionToCheck: String, millis: Long) = this(conditionToCheck + " (not met within " + millis + " millis)")
}