*/
if (m_snapshotPriority > 0) {
final long now = System.currentTimeMillis();
//Ask if the site is idle, and if it is queue the work immediately
if (m_idlePredicate.idle(now)) {
m_siteTaskerQueue.offer(new SnapshotTask());
return;
}
//Cache the value locally, the dirty secret is that in edge cases multiple threads
//will read/write briefly, but it isn't a big deal since the scheduling can be wrong
//briefly. Caching it locally will make the logic here saner because it can't change
//as execution progresses
final long quietUntil = m_quietUntil;
/*
* If the current time is > than quietUntil then the quiet period is over
* and the snapshot work should be done immediately
*
* Otherwise it needs to be scheduled in the future and the next quiet period
* needs to be calculated
*/
if (now > quietUntil) {
m_siteTaskerQueue.offer(new SnapshotTask());
//Now push the quiet period further into the future,
//generally no threads will be racing to do this
//since the execution site only interacts with one snapshot data target at a time
//except when it is switching tables. It doesn't really matter if it is wrong
//it will just result in a little extra snapshot work being done close together
m_quietUntil =
System.currentTimeMillis() +
(5 * m_snapshotPriority) + ((long)(m_random.nextDouble() * 15));
} else {
//Schedule it to happen after the quiet period has elapsed
VoltDB.instance().schedulePriorityWork(
new Runnable() {
@Override
public void run()
{
m_siteTaskerQueue.offer(new SnapshotTask());
}
},
quietUntil - now,
0,
TimeUnit.MILLISECONDS);
/*
* This is the same calculation as above except the future is not based
* on the current time since the quiet period was already in the future
* and we need to move further past it since we just scheduled snapshot work
* at the end of the current quietUntil value
*/
m_quietUntil =
quietUntil +
(5 * m_snapshotPriority) + ((long)(m_random.nextDouble() * 15));
}
} else {
m_siteTaskerQueue.offer(new SnapshotTask());
}
}