/** * Adds an old value with a fixed timestamp to the sample. * * @param value the value to be added * @param timestamp the epoch timestamp of {@code value} in seconds */ public void update(long value, long timestamp) { lockForRegularUsage(); try { final double priority = weight(timestamp - startTime) / random(); final long newCount = count.incrementAndGet(); if (newCount <= reservoirSize) { values.put(priority, value); } else { Double first = values.firstKey(); if (first < priority) { if (values.putIfAbsent(priority, value) == null) { // ensure we always remove an item while (values.remove(first) == null) { first = values.firstKey(); } } } } } finally { unlockForRegularUsage(); } final long now = System.nanoTime(); final long next = nextScaleTime.get(); if (now >= next) { rescale(now, next); } }
/** Sleeps until the next task in line is ready to be executed */ protected void waitUntilNextExecution() { lock.lock(); try { if (!running) return; next_execution_time = tasks.firstKey(); long sleep_time = next_execution_time - System.currentTimeMillis(); tasks_available.await(sleep_time, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { } finally { lock.unlock(); } }
/** * Adds an old value with a fixed timestamp to the reservoir. * * @param value the value to be added * @param timestamp the epoch timestamp of {@code value} in seconds */ public void update(long value, long timestamp) { rescaleIfNeeded(); lockForRegularUsage(); try { final double itemWeight = weight(timestamp - startTime); final WeightedSample sample = new WeightedSample(value, itemWeight); final double priority = itemWeight / ThreadLocalRandom.current().nextDouble(); final long newCount = count.incrementAndGet(); if (newCount <= size) { values.put(priority, sample); } else { Double first = values.firstKey(); if (first < priority && values.putIfAbsent(priority, sample) == null) { // ensure we always remove an item while (values.remove(first) == null) { first = values.firstKey(); } } } } finally { unlockForRegularUsage(); } }
protected void cleanupCalls(long rpcTimeout) { Iterator<Entry<Integer, Call>> itor = calls.entrySet().iterator(); while (itor.hasNext()) { Call c = itor.next().getValue(); long waitTime = System.currentTimeMillis() - c.getStartTime(); if (waitTime >= rpcTimeout) { if (this.closeException == null) { // There may be no exception in the case that there are many calls // being multiplexed over this connection and these are succeeding // fine while this Call object is taking a long time to finish // over on the server; e.g. I just asked the regionserver to bulk // open 3k regions or its a big fat multiput into a heavily-loaded // server (Perhaps this only happens at the extremes?) this.closeException = new CallTimeoutException( "Call id=" + c.id + ", waitTime=" + waitTime + ", rpcTimetout=" + rpcTimeout); } c.setException(this.closeException); synchronized (c) { c.notifyAll(); } itor.remove(); } else { break; } } try { if (!calls.isEmpty()) { Call firstCall = calls.get(calls.firstKey()); long maxWaitTime = System.currentTimeMillis() - firstCall.getStartTime(); if (maxWaitTime < rpcTimeout) { rpcTimeout -= maxWaitTime; } } if (!shouldCloseConnection.get()) { closeException = null; if (socket != null) { socket.setSoTimeout((int) rpcTimeout); } } } catch (SocketException e) { LOG.debug("Couldn't lower timeout, which may result in longer than expected calls"); } }