JobGenerator中有一個timer成員,根據配置中的時間間隔不斷產生GenerateJobs事件來觸發job的產生,以成爲job產生的起點。Timer通過clock來作爲構建時間的依據。
val clock = {
val clockClass = ssc.sc.conf.get(
"spark.streaming.clock", "org.apache.spark.util.SystemClock")
try {
Utils.classForName(clockClass).newInstance().asInstanceOf[Clock]
} catch {
case e: ClassNotFoundException if clockClass.startsWith("org.apache.spark.streaming") =>
val newClockClass = clockClass.replace("org.apache.spark.streaming", "org.apache.spark")
Utils.classForName(newClockClass).newInstance().asInstanceOf[Clock]
}
}
Clock的默認實現是SystemClock,其實現其實就是調用系統api獲得當前時間。
def getTimeMillis(): Long = System.currentTimeMillis()
並實現了waitTillTime()方法用來等待直到目標時間到達。
def waitTillTime(targetTime: Long): Long = {
var currentTime = 0L
currentTime = System.currentTimeMillis()
var waitTime = targetTime - currentTime
if (waitTime <= 0) {
return currentTime
}
val pollTime = math.max(waitTime / 10.0, minPollTime).toLong
while (true) {
currentTime = System.currentTimeMillis()
waitTime = targetTime - currentTime
if (waitTime <= 0) {
return currentTime
}
val sleepTime = math.min(waitTime, pollTime)
Thread.sleep(sleepTime)
}
-1
}
此處實現的細節,並不是計算完畢當前的時間和系統事件的差距而直接進行sleep相應的時間,而是首先計算距離當前時間的十分之一(但不能小於0.025秒),作爲單次的最大休眠時間,該線程會不斷sleep最大休眠時間與距離目標時間差距時間的小者,以便在分段休眠中達到儘可能精確的目的。
private val timer = new RecurringTimer(clock, ssc.graph.batchDuration.milliseconds,
longTime => eventLoop.post(GenerateJobs(new Time(longTime))), "JobGenerator")
而後在JobGenerator將會把clock作爲入參構建一個RecuringTimer,並在這裏實現了callback函數用來在達到時間的時候向eventloop發送GenerateJobs事件驅動job生成,生成job的時間間隔也就是在StreamingContext中配置的生成批的間隔。
private def triggerActionForNextInterval(): Unit = {
clock.waitTillTime(nextTime)
callback(nextTime)
prevTime = nextTime
nextTime += period
logDebug("Callback for " + name + " called at time " + prevTime)
}
private def loop() {
try {
while (!stopped) {
triggerActionForNextInterval()
}
triggerActionForNextInterval()
} catch {
case e: InterruptedException =>
}
}
在timer的實現RecuringTimer中,實則實現了一個線程不斷調用loop方法,在loop方法中將會調用triggerActionForNextInterval()方法通過上述的clock的waitTillTime()方法在配置好的時間間隔之後觸發上文的作爲入參傳遞的callback函數向eventloop發送GenerateJobs事件驅動job生成。