package com.robonobo.common.concurrent; import java.util.*; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * Like Batcher, but limits the number of items batched per run - if any items are left after a run, the batcher will * run again after the specified interval * * @author macavity */ public abstract class RateLimitedBatcher<T> extends Batcher<T> { protected int rateLimit; public RateLimitedBatcher(long timespanMs, ScheduledThreadPoolExecutor executor, int rateLimit) { super(timespanMs, executor); this.rateLimit = rateLimit; } @Override public void doRun() throws Exception { List<T> runObjs; lock.lock(); task = null; if (queuedObjs.size() <= rateLimit) { runObjs = queuedObjs; queuedObjs = new ArrayList<T>(); } else { runObjs = new ArrayList<T>(); Iterator<T> it = queuedObjs.iterator(); for (int i = 0; i < rateLimit; i++) { runObjs.add(it.next()); it.remove(); } // Reschedule our task to pick up the remainder task = executor.schedule(this, timespanMs, TimeUnit.MILLISECONDS); } lock.unlock(); runBatch(runObjs); } }