Skip to content

Commit eb22ff3

Browse files
committed
Added comments in Client.java.
Added doesWrites() to MultiDeleteRequest. Updated SimpleRateLimiter to delay properly with usePercent != 100.0 and units == 0.
1 parent 5b4e1f1 commit eb22ff3

File tree

3 files changed

+58
-3
lines changed

3 files changed

+58
-3
lines changed

driver/src/main/java/oracle/nosql/driver/http/Client.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import static oracle.nosql.driver.util.LogUtil.logFine;
1616
import static oracle.nosql.driver.util.LogUtil.logInfo;
1717
import static oracle.nosql.driver.util.LogUtil.logTrace;
18-
import static oracle.nosql.driver.util.BinaryProtocol.READ_KB_LIMIT;
1918
import static oracle.nosql.driver.util.HttpConstants.ACCEPT;
2019
import static oracle.nosql.driver.util.HttpConstants.CONNECTION;
2120
import static oracle.nosql.driver.util.HttpConstants.CONTENT_LENGTH;
@@ -729,6 +728,25 @@ private int consumeLimiterUnits(RateLimiter rl, long units,
729728
return 0;
730729
}
731730

731+
/*
732+
* The logic consumes units (and potentially delays) _after_ a
733+
* successful operation for a few reasons:
734+
* 1) We don't know the actual number of units an op uses unitl
735+
* after the operation successfully finishes
736+
* 2) Delaying after the op keeps the application from immediately
737+
* trying the next op and ending up waiting along with other
738+
* client threads until the rate goes below the limit, at which
739+
* time all client threads would continue at once. By waiting
740+
* after a successful op, client threads will get staggered
741+
* better to avoid spikes in throughput and oscillation that
742+
* can result from it.
743+
* 3) For operations that use less than 100% of the limits (i.e.
744+
* they set a usePercent to less than 100), this is the only place
745+
* where the delay time may be longer, because the pre-operation
746+
* "wait for below the limit" limiter checks do not take usePercent
747+
* into account.
748+
*/
749+
732750
double usePercent = request.getRateLimiterPercentage();
733751
if (usePercent == 0.0) {
734752
usePercent = config.getDefaultRateLimitingPercentage();

driver/src/main/java/oracle/nosql/driver/ops/MultiDeleteRequest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,4 +235,12 @@ public void validate() {
235235
public boolean doesReads() {
236236
return true;
237237
}
238+
239+
/**
240+
* @hidden
241+
*/
242+
@Override
243+
public boolean doesWrites() {
244+
return true;
245+
}
238246
}

driver/src/main/java/oracle/nosql/driver/util/SimpleRateLimiter.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,10 +375,9 @@ private synchronized int consumeInternalPercent(long units, int timeoutMs,
375375
* the logic will only consume the given amount, but will
376376
* return a sleep time proportional to the usePercent
377377
*/
378-
long nanosAdded = 0;
379378
long infunits = (long)((double)units / usePercent);
380379
long inflatedNanos = infunits * nanosPerUnit;
381-
nanosAdded = inflatedNanos - nanosNeeded;
380+
long nanosAdded = inflatedNanos - nanosNeeded;
382381

383382
/*
384383
* if the new last nano is less than now, the consume
@@ -411,6 +410,15 @@ private synchronized int consumeInternalPercent(long units, int timeoutMs,
411410
sleepMs = 1;
412411
}
413412

413+
/*
414+
* if this was called to get the time before the limiter is below its
415+
* limit, adjust the time based on usePercentage (this is easier to
416+
* adjust for here instead of trying to factor it into the math above).
417+
*/
418+
if (units == 0) {
419+
sleepMs = (int)((double)sleepMs / usePercent);
420+
}
421+
414422
if (alwaysConsume) {
415423
/*
416424
* if we're told to always consume the units no matter what,
@@ -514,4 +522,25 @@ private void uninterruptibleSleep(int sleepMs) {
514522
}
515523
}
516524

525+
526+
/**
527+
* @hidden
528+
* Consumes units and returns the time to sleep.
529+
*
530+
* Note this method returns immediately in all cases. It returns
531+
* the number of milliseconds to sleep.
532+
*
533+
* @param units number of units to attempt to consume
534+
* @return number of milliseconds to sleep.
535+
* If the return value is zero, the consume succeeded under the
536+
* limit and no sleep is necessary.
537+
*/
538+
public int consumeExternally(long units) {
539+
/* If disabled, just return success */
540+
if (nanosPerUnit <= 0) {
541+
return 0;
542+
}
543+
return consumeInternalFull(units, 0, true, System.nanoTime());
544+
}
545+
517546
}

0 commit comments

Comments
 (0)