public <C> DelayLimiter<C> build() { return new DelayLimiter<>(this); }
public final void clear() { delayLimiter.clear(); } }
/** Returns true if a given context should be invoked. */ public boolean shouldInvoke(C context) { cleanupExpiredSuppressions(); if (cache.containsKey(context)) return false; Suppression<C> suppression = new Suppression<>(ticker, context, ticker.read() + ttlNanos); if (cache.putIfAbsent(context, suppression) != null) return false; // lost race suppressions.offer(suppression); // If we added an entry, it could make us go over the max size. if (suppressions.size() > cardinality) removeOneSuppression(); return true; }
@Override protected ResultSet doExecute() throws IOException { try { return super.doExecute(); } catch (IOException | RuntimeException | Error e) { factory.delayLimiter.invalidate(input); throw e; } }
public final Call<ResultSet> create(I input) { if (input == null) throw new NullPointerException("input == null"); if (!delayLimiter.shouldInvoke(input)) return Call.create(null); return newCall(input); }
protected Factory(int ttl, int cardinality) { delayLimiter = DelayLimiter.newBuilder().ttl(ttl).cardinality(cardinality).build(); }
@Override public void onError(Throwable t) { factory.delayLimiter.invalidate(input); callback.onError(t); } });
@Override protected void doCancel() { factory.delayLimiter.invalidate(input); super.doCancel(); } }