From 040db4782fa42b92f2f36c8dc69f2e81db0396cd Mon Sep 17 00:00:00 2001 From: Jonathan Shook Date: Mon, 7 Dec 2020 13:41:27 -0600 Subject: [PATCH] backport github actions breaking change fix --- .nosqlbench/grafana_apikey | 1 + .../ratelimits/InlineTokenPool.java | 376 +++++++++++ sort_docs/design/opstate.puml | 61 ++ sort_docs/eb_iterates_cycles.puml | 29 + sort_docs/eb_iterates_cycles.svg | 221 +++++++ sort_docs/eb_iterates_phases.puml | 42 ++ sort_docs/eb_iterates_phases.svg | 284 ++++++++ sort_docs/eb_latency_details.puml | 38 ++ sort_docs/eb_latency_terms.puml | 30 + sort_docs/eb_latency_terms.svg | 235 +++++++ sort_docs/op_state_nomnoml.png | Bin 0 -> 59238 bytes sort_docs/opstate_nomnoml.svg | 78 +++ sort_docs/package_layout.md | 7 + sort_docs/parts.puml | 0 sort_docs/rate_limiter_design.puml | 82 +++ sort_docs/ratelimiter_timelines.puml | 47 ++ sort_docs/research/multivariate.svg | 540 ++++++++++++++++ sort_docs/research/op_tracking.svg | 611 ++++++++++++++++++ sort_docs/testseq_early.png | Bin 0 -> 25703 bytes sort_docs/testseq_early.puml | 45 ++ sort_docs/testseq_late.png | Bin 0 -> 25478 bytes sort_docs/testseq_late.puml | 51 ++ sort_docs/todo.md | 16 + 23 files changed, 2794 insertions(+) create mode 100644 .nosqlbench/grafana_apikey create mode 100644 engine-api/src/main/java/io/nosqlbench/engine/api/activityapi/ratelimits/InlineTokenPool.java create mode 100644 sort_docs/design/opstate.puml create mode 100644 sort_docs/eb_iterates_cycles.puml create mode 100644 sort_docs/eb_iterates_cycles.svg create mode 100644 sort_docs/eb_iterates_phases.puml create mode 100644 sort_docs/eb_iterates_phases.svg create mode 100644 sort_docs/eb_latency_details.puml create mode 100644 sort_docs/eb_latency_terms.puml create mode 100644 sort_docs/eb_latency_terms.svg create mode 100644 sort_docs/op_state_nomnoml.png create mode 100644 sort_docs/opstate_nomnoml.svg create mode 100644 sort_docs/package_layout.md create mode 100644 sort_docs/parts.puml create mode 100644 sort_docs/rate_limiter_design.puml create mode 100644 sort_docs/ratelimiter_timelines.puml create mode 100644 sort_docs/research/multivariate.svg create mode 100644 sort_docs/research/op_tracking.svg create mode 100644 sort_docs/testseq_early.png create mode 100644 sort_docs/testseq_early.puml create mode 100644 sort_docs/testseq_late.png create mode 100644 sort_docs/testseq_late.puml create mode 100644 sort_docs/todo.md diff --git a/.nosqlbench/grafana_apikey b/.nosqlbench/grafana_apikey new file mode 100644 index 000000000..11d760aed --- /dev/null +++ b/.nosqlbench/grafana_apikey @@ -0,0 +1 @@ +eyJrIjoibVFjRkV5Z096VHE0MjhXYk1RM2p1cnFuUkhQMXVZNGwiLCJuIjoibm9zcWxiZW5jaC0xMC4xMC4xMDAuNTItMTYwNzMxMDE2MDM0OCIsImlkIjoxfQ== \ No newline at end of file diff --git a/engine-api/src/main/java/io/nosqlbench/engine/api/activityapi/ratelimits/InlineTokenPool.java b/engine-api/src/main/java/io/nosqlbench/engine/api/activityapi/ratelimits/InlineTokenPool.java new file mode 100644 index 000000000..dfbfc8f36 --- /dev/null +++ b/engine-api/src/main/java/io/nosqlbench/engine/api/activityapi/ratelimits/InlineTokenPool.java @@ -0,0 +1,376 @@ +/* + * + * Copyright 2016 jshook + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ + +package io.nosqlbench.engine.api.activityapi.ratelimits; + +import com.codahale.metrics.Timer; +import io.nosqlbench.engine.api.activityimpl.ActivityDef; +import io.nosqlbench.engine.api.metrics.ActivityMetrics; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.LockSupport; +import java.util.concurrent.locks.ReentrantLock; + +import static io.nosqlbench.engine.api.util.Colors.*; + +/** + *

Synopsis

+ * + * This TokenPool represents a finite quantity which can be + * replenished with regular refills. Extra tokens that do not fit + * within the active token pool are saved in a waiting token pool and + * used to backfill when allowed according to the backfill rate. + * + * A detailed explanation for how this works will be included + * at @link "http://docs.nosqlbench.io/" under dev notes. + * + *

This is the basis for the token-based rate limiters in + * NB. This mechanism is easily adaptable to bursting + * capability as well as a degree of stricter timing at speed. + * Various methods for doing this in a lock free way were + * investigated, but the intrinsic locks provided by synchronized + * method won out for now. This may be revisited when EB is + * retrofitted for J11. + *

+ */ +public class InlineTokenPool { + + private final static Logger logger = LogManager.getLogger(InlineTokenPool.class); + + public static final double MIN_CONCURRENT_OPS = 5; + + // Size limit of active pool + private long maxActivePoolSize; + // Size limit of burst pool incremental above active pool + private long maxBurstPoolSize; + // Size limit of total active tokens which can be waiting in active pool, considering burst + private long maxActiveAndBurstSize; + + // Ratio of speed relative to base speed at which bursting is allowed + private double burstRatio; + + // TODO Consider removing volatile after investigating + + // The active number of tokens (ns) available for consumers + private volatile long activePool; + // The tokens which were not claimed on time, and were moved into the waitime (reserve) pool + private volatile long waitingPool; + // How many tokens (ns) represent passage of time for a single op, given the op rate + private long nanosPerOp; + + // The nanotime of the last refill + private volatile long lastRefillAt; + // metrics for refill + private final Timer refillTimer; + // update rate for refiller + private final long interval = (long) 1E6; + + + private RateSpec rateSpec; +// private long debugTrigger=0L; +// private long debugRate=1000000000; + + // Total number of thread blocks that occured since this token pool was started + private long blocks = 0L; + + private final Lock lock = new ReentrantLock(); + private final Condition lockheld = lock.newCondition(); + + /** + * This constructor tries to pick reasonable defaults for the token pool for + * a given rate spec. The active pool must be large enough to contain one + * op worth of time, and the burst ratio + * + * @param rateSpec a {@link RateSpec} + */ + public InlineTokenPool(RateSpec rateSpec, ActivityDef def) { + ByteBuffer logbuf = getBuffer(); + apply(rateSpec); + logger.debug("initialized token pool: " + this.toString() + " for rate:" + rateSpec.toString()); + this.refillTimer = ActivityMetrics.timer(def, "tokenfiller"); + } + + public InlineTokenPool(long poolsize, double burstRatio, ActivityDef def) { + ByteBuffer logbuf = getBuffer(); + this.maxActivePoolSize = poolsize; + this.burstRatio = burstRatio; + this.maxActiveAndBurstSize = (long) (maxActivePoolSize * burstRatio); + this.maxBurstPoolSize = maxActiveAndBurstSize - maxActivePoolSize; + this.refillTimer = ActivityMetrics.timer(def, "tokenfiller"); + } + + /** + * Change the settings of this token pool, and wake any blocked callers + * just in case it allows them to proceed. + * + * @param rateSpec The rate specifier. + */ + public synchronized void apply(RateSpec rateSpec) { + this.rateSpec = rateSpec; + // maxActivePool is set to the higher of 1M or however many nanos are needed for 2 ops to be buffered + this.maxActivePoolSize = Math.max((long) 1E6, (long) ((double) rateSpec.getNanosPerOp() * MIN_CONCURRENT_OPS)); + this.maxActiveAndBurstSize = (long) (maxActivePoolSize * rateSpec.getBurstRatio()); + this.burstRatio = rateSpec.getBurstRatio(); + + this.maxBurstPoolSize = maxActiveAndBurstSize - maxActivePoolSize; + this.nanosPerOp = rateSpec.getNanosPerOp(); + notifyAll(); + } + + + public double getBurstRatio() { + return burstRatio; + } + + /** + * Take tokens up to amt tokens form the pool and report + * the amount of token removed. + * + * @param amt tokens requested + * @return actual number of tokens removed, greater to or equal to zero + */ + public synchronized long takeUpTo(long amt) { + long take = Math.min(amt, activePool); + activePool -= take; + return take; + } + + /** + * wait for the given number of tokens to be available, and then remove + * them from the pool. + * + * @return the total number of tokens untaken, including wait tokens + */ + public long blockAndTake() { + synchronized (this) { + if (activePool >= nanosPerOp) { + activePool -= nanosPerOp; + return waitingPool + activePool; + } + } + while (true) { + if (lock.tryLock()) { + try { + while (activePool < nanosPerOp) { + dorefill(); + } + lockheld.signal(); + lockheld.signal(); + } finally { + lock.unlock(); + } + } else { + try { + lockheld.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } +// while (activePool < nanosPerOp) { +// blocks++; +// //System.out.println(ANSI_BrightRed + "waiting for " + amt + "/" + activePool + " of max " + maxActivePool + ANSI_Reset); +// try { +// wait(); +//// wait(maxActivePoolSize / 1000000, (int) maxActivePoolSize % 1000000); +// } catch (InterruptedException ignored) { +// } catch (Exception e) { +// throw new RuntimeException(e); +// } +// //System.out.println("waited for " + amt + "/" + activePool + " tokens"); +// } +// //System.out.println(ANSI_BrightYellow + "taking " + amt + "/" + activePool + ANSI_Reset); +// +// activePool -= nanosPerOp; +// return waitingPool + activePool; + } + + public synchronized long blockAndTakeOps(long ops) { + long totalNanosNeeded = ops * nanosPerOp; + while (activePool < totalNanosNeeded) { + blocks++; + //System.out.println(ANSI_BrightRed + "waiting for " + amt + "/" + activePool + " of max " + maxActivePool + ANSI_Reset); + try { + wait(); +// wait(maxActivePoolSize / 1000000, (int) maxActivePoolSize % 1000000); + } catch (InterruptedException ignored) { + } catch (Exception e) { + throw new RuntimeException(e); + } + //System.out.println("waited for " + amt + "/" + activePool + " tokens"); + } + //System.out.println(ANSI_BrightYellow + "taking " + amt + "/" + activePool + ANSI_Reset); + + activePool -= totalNanosNeeded; + return waitingPool + activePool; + } + + public synchronized long blockAndTake(long tokens) { + while (activePool < tokens) { + //System.out.println(ANSI_BrightRed + "waiting for " + amt + "/" + activePool + " of max " + maxActivePool + ANSI_Reset); + try { + wait(); +// wait(maxActivePoolSize / 1000000, (int) maxActivePoolSize % 1000000); + } catch (InterruptedException ignored) { + } catch (Exception e) { + throw new RuntimeException(e); + } + //System.out.println("waited for " + amt + "/" + activePool + " tokens"); + } + //System.out.println(ANSI_BrightYellow + "taking " + amt + "/" + activePool + ANSI_Reset); + + activePool -= tokens; + return waitingPool + activePool; + } + + public long getWaitTime() { + return activePool + waitingPool; + } + + public long getWaitPool() { + return waitingPool; + } + + public long getActivePool() { + return activePool; + } + + /** + * Add the given number of new tokens to the pool, forcing any amount + * that would spill over the current pool size into the wait token pool, but + * moving up to the configured burst tokens back from the wait token pool + * otherwise. + * + * The amount of backfilling that occurs is controlled by the backfill ratio, + * based on the number of tokens submitted. This causes normalizes the + * backfilling rate to the fill rate, so that it is not sensitive to refill + * scheduling. + * + * @param newTokens The number of new tokens to add to the token pools + * @return the total number of tokens in all pools + */ + public synchronized long refill(long newTokens) { + boolean debugthis = false; +// long debugAt = System.nanoTime(); +// if (debugAt>debugTrigger+debugRate) { +// debugTrigger=debugAt; +// debugthis=true; +// } + + long needed = Math.max(maxActivePoolSize - activePool, 0L); + long allocatedToActivePool = Math.min(newTokens, needed); + activePool += allocatedToActivePool; + + + // overflow logic + long allocatedToOverflowPool = newTokens - allocatedToActivePool; + waitingPool += allocatedToOverflowPool; + + // backfill logic + double refillFactor = Math.min((double) newTokens / maxActivePoolSize, 1.0D); + long burstFillAllowed = (long) (refillFactor * maxBurstPoolSize); + + burstFillAllowed = Math.min(maxActiveAndBurstSize - activePool, burstFillAllowed); + long burstFill = Math.min(burstFillAllowed, waitingPool); + + waitingPool -= burstFill; + activePool += burstFill; + + if (debugthis) { + System.out.print(this); + System.out.print(ANSI_BrightBlue + " adding=" + allocatedToActivePool); + if (allocatedToOverflowPool > 0) { + System.out.print(ANSI_Red + " OVERFLOW:" + allocatedToOverflowPool + ANSI_Reset); + } + if (burstFill > 0) { + System.out.print(ANSI_BrightGreen + " BACKFILL:" + burstFill + ANSI_Reset); + } + System.out.println(); + } + + //System.out.println(this); + notifyAll(); + + return activePool + waitingPool; + } + + @Override + public String toString() { + return "Tokens: active=" + activePool + "/" + maxActivePoolSize + + String.format( + " (%3.1f%%)A (%3.1f%%)B ", + (((double) activePool / (double) maxActivePoolSize) * 100.0), + (((double) activePool / (double) maxActiveAndBurstSize) * 100.0)) + " waiting=" + waitingPool + + " blocks=" + blocks + + " rateSpec:" + ((rateSpec != null) ? rateSpec.toString() : "NULL"); + } + + public RateSpec getRateSpec() { + return rateSpec; + } + + public synchronized long restart() { + long wait = activePool + waitingPool; + activePool = 0L; + waitingPool = 0L; + return wait; + } + + private ByteBuffer getBuffer() { + RandomAccessFile image = null; + try { + image = new RandomAccessFile("tokenbucket.binlog", "rw"); + ByteBuffer mbb = image.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, image.length()); + return mbb; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public synchronized void dorefill() { + lastRefillAt = System.nanoTime(); + long nextRefillTime = lastRefillAt + interval; + long thisRefillTime = System.nanoTime(); + while (thisRefillTime < nextRefillTime) { +// while (thisRefillTime < lastRefillAt + interval) { + long parkfor = Math.max(nextRefillTime - thisRefillTime, 0L); + //System.out.println(ANSI_Blue + "parking for " + parkfor + "ns" + ANSI_Reset); + LockSupport.parkNanos(parkfor); + thisRefillTime = System.nanoTime(); + } + +// this.times[iteration]=thisRefillTime; + long delta = thisRefillTime - lastRefillAt; +// this.amounts[iteration]=delta; + lastRefillAt = thisRefillTime; + + //System.out.println(this); + refill(delta); + refillTimer.update(delta, TimeUnit.NANOSECONDS); +// iteration++; + + } + + +} diff --git a/sort_docs/design/opstate.puml b/sort_docs/design/opstate.puml new file mode 100644 index 000000000..eb6be73d4 --- /dev/null +++ b/sort_docs/design/opstate.puml @@ -0,0 +1,61 @@ +@startuml +scale 600 width +[*] --> TrackedOp : track() + + TrackedOp: setCycle(cycle) + TrackedOp: setWaitTime(delay) + TrackedOp: start() + TrackedOp: + TrackedOp: setData(data) + TrackedOp: getData() + TrackedOp: skip(reason) + +State InProtocol { + + TrackedOp --> StartedOp : start() + + StartedOp: getCycle() + StartedOp: setData(data) + StartedOp: getData() + StartedOp: succeed(status) + StartedOp: + StartedOp: retry() + StartedOp: fail(status) + StartedOp: getStartedAtNanos() + StartedOp: getCurrentServiceTimeNanos() + StartedOp: getCurrentResponseTimeNanos() + + StartedOp -> StartedOp : retry() + + StartedOp --> SucceededOp : succeed() + SucceededOp: getCycle() + SucceededOp: getResult() + SucceededOp: getTries() + SucceededOp: getStartedAtNanos() + SucceededOp: getServiceTimeNanos() + SucceededOp: getResponseTimeNanos() + + StartedOp --> FailedOp: fail() + FailedOp: getCycle() + FailedOp: getResult() + FailedOp: getTries() + FailedOp: getStartedAtNanos() + FailedOp: getServiceTimeNanos() + FailedOp: getResponseTimeNanos() +} + +TrackedOp --> SkippedOp : skip() +SkippedOp: getSkippedReason() +SkippedOp: +SkippedOp: getCycle() +SkippedOp: getResult() +SkippedOp: getStartedAtNanos() +SkippedOp: getData() +SkippedOp: setData(data) + + +SucceededOp --> [*] +FailedOp --> [*] +SkippedOp --> [*] + +@enduml \ No newline at end of file diff --git a/sort_docs/eb_iterates_cycles.puml b/sort_docs/eb_iterates_cycles.puml new file mode 100644 index 000000000..15d22bfca --- /dev/null +++ b/sort_docs/eb_iterates_cycles.puml @@ -0,0 +1,29 @@ +@startuml + +Participant Input as i +Participant Thread as t +Participant Action as a + +== acquire input == + +group TIMER read-input + t -> i : get segment(stride) + activate i + t <- i : [stride] + deactivate i +end + +group TIMER strides + + loop over cycle values in segment + group TIMER cycle & phase + t -> a : runCycle(cycle) + activate a + t <- a : result + deactivate a + end +end + +end # strides + +@enduml \ No newline at end of file diff --git a/sort_docs/eb_iterates_cycles.svg b/sort_docs/eb_iterates_cycles.svg new file mode 100644 index 000000000..d7e447ca2 --- /dev/null +++ b/sort_docs/eb_iterates_cycles.svg @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + Input + + + Input + + + Thread + + + Thread + + + Action + + + Action + + + + + + + + acquire input + + + + TIMER read-input + + + + get segment(stride) + + + + <cycle segment>[stride] + + + + TIMER strides + + + + loop + + [over cycle + values in segment] + + + + TIMER cycle + & phase + + + + runCycle(cycle) + + + + result + + + \ No newline at end of file diff --git a/sort_docs/eb_iterates_phases.puml b/sort_docs/eb_iterates_phases.puml new file mode 100644 index 000000000..ff3d1c82a --- /dev/null +++ b/sort_docs/eb_iterates_phases.puml @@ -0,0 +1,42 @@ +@startuml + +Participant Input as i +Participant Thread as t +Participant Action as a + +== acquire input data == + +group TIMER read-input + t -> i : get segment(stride) + activate i + t <- i : [stride] + deactivate i +end + +group TIMER strides + + loop over cycle values in segment + group TIMER cycle + group TIMER phase + t -> a : runCycle(cycle) + activate a + t <- a : result + deactivate a + end + +== additional phases == + +group TIMER phase + loop until phases complete + t -> a : runPhase(cycle) + activate a + t <- a : result + deactivate a +end +end +end +end + +end # strides + +@enduml \ No newline at end of file diff --git a/sort_docs/eb_iterates_phases.svg b/sort_docs/eb_iterates_phases.svg new file mode 100644 index 000000000..577addfd1 --- /dev/null +++ b/sort_docs/eb_iterates_phases.svg @@ -0,0 +1,284 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Input + + + Input + + + Thread + + + Thread + + + Action + + + Action + + + + + + + + + acquire input + data + + + + TIMER read-input + + + + get segment(stride) + + + + <cycle segment>[stride] + + + + TIMER strides + + + + loop + + [over cycle + values in segment] + + + + TIMER cycle + + + + TIMER phase + + + + runCycle(cycle) + + + + result + + + + + + additional + phases + + + + TIMER phase + + + + loop + + [until phases + complete] + + + + runPhase(cycle) + + + + result + + + \ No newline at end of file diff --git a/sort_docs/eb_latency_details.puml b/sort_docs/eb_latency_details.puml new file mode 100644 index 000000000..9081a4928 --- /dev/null +++ b/sort_docs/eb_latency_details.puml @@ -0,0 +1,38 @@ +@startuml +Participant user as u +Participant client as c +Participant resource as cr +Participant transport as t +Participant server as s + +group responsetime + u -> c: request + activate c #Black + group waittime + c -> cr: wait + activate cr #Yellow + note left of cr: client\nwaits\nfor\nresource + cr -> c: + deactivate cr + end + + group servicetime + c ->> t: request + activate t #Red + group servertime + t ->> s: request + deactivate t + activate s #Blue + note right of s: server\nprocesses\nrequest + s ->> t: response + deactivate s + activate t #Red + end + t ->> c: response + deactivate t + end + c -> u: response + deactivate c +end + +@enduml \ No newline at end of file diff --git a/sort_docs/eb_latency_terms.puml b/sort_docs/eb_latency_terms.puml new file mode 100644 index 000000000..c7f6d336a --- /dev/null +++ b/sort_docs/eb_latency_terms.puml @@ -0,0 +1,30 @@ +@startuml +Participant user as u +Participant client as c +Participant resource as cr +Participant server as s + +group responsetime + u -> c: request + activate c #Black +' note left of c: user\nwaits\nfor\nresponse + group waittime + c -> cr: wait + activate cr #Yellow + note right of cr: client\nwaits\nfor\nresource + cr -> c: + deactivate cr + end + + group servicetime + c ->> s: request + activate s #Blue + note right of s: server\nprocesses\nrequest + s ->> c: response + deactivate s + end + c -> u: response + deactivate c +end + +@enduml \ No newline at end of file diff --git a/sort_docs/eb_latency_terms.svg b/sort_docs/eb_latency_terms.svg new file mode 100644 index 000000000..ccfe22776 --- /dev/null +++ b/sort_docs/eb_latency_terms.svg @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + user + + + user + + + client + + + client + + + resource + + + resource + + + server + + + server + + + + + + + responsetime + + + + request + + + + waittime + + + + wait + + + + client + + waits + + for + + resource + + + + + + servicetime + + + + + request + + + + server + + processes + + request + + + + + response + + + + response + + + \ No newline at end of file diff --git a/sort_docs/op_state_nomnoml.png b/sort_docs/op_state_nomnoml.png new file mode 100644 index 0000000000000000000000000000000000000000..fbeea86f5ed1b1964f9cdd6f3636e8788eadd548 GIT binary patch literal 59238 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�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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + track + start + skip + retry + succeed + fail + + tracked + + started + + succeeded + + failed + + skipped + \ No newline at end of file diff --git a/sort_docs/package_layout.md b/sort_docs/package_layout.md new file mode 100644 index 000000000..2705d7f51 --- /dev/null +++ b/sort_docs/package_layout.md @@ -0,0 +1,7 @@ +- io.nosqlbench.engine. +- io.nosqlbench.extensions. +- io.nosqlbench.activitytypes. + +- io.nosqlbench.virtdata. +- io.nosqlbench.virtdata.library. +- io.nosqlbench.docs. ... \ No newline at end of file diff --git a/sort_docs/parts.puml b/sort_docs/parts.puml new file mode 100644 index 000000000..e69de29bb diff --git a/sort_docs/rate_limiter_design.puml b/sort_docs/rate_limiter_design.puml new file mode 100644 index 000000000..8a97ff202 --- /dev/null +++ b/sort_docs/rate_limiter_design.puml @@ -0,0 +1,82 @@ +@startuml + +Participant "Calling\nThread" as t +Participant "Limiter\nlogic" as l +Participant "Allocated\nnanos" as a +Participant "Elapsed\nnanos" as e +Participant "Clock\nSource" as c + +t -> l : acquire(nanos) + +group allocate start time +l -> a : getAndIncrement(nanos) +activate a #black +note over l,a + **allocated** is an atomic accumulator + which represents scheduled time. Each + op causes it to be atomically incremented + by a time slice of nanos. +end note +a -> l : +deactivate a +end + +group calculate delay (cached) +l -> e : get() +activate e +note over e + **elapsed** is an + atomic register + which caches + system time. +end note +e -> l : +deactivate e +l -> l : delay = \nelapsed - scheduled_at + +note right + **delay** measures external delay + that causes an op to fire after + the ideal time. **positive delay** + thus means the rate limiter doesn't + need to impose its own blocking delay + in order to ensure delay>=0. +end note + +end + +group if delay<0 (cached) +note over l,c + If delay<0, then this operation is too soon according + to the cached clock value. Since this could be stale + and cause us to block needlessly, we update the cached + clock value and recompute delay. +end note +l -> c : get() (~25ns) +activate c #orange +c -> l : +deactivate c + +l -> e : store() +activate e #black +e -> l +deactivate e +l -> l : delay = \nelapsed - scheduled_at + +group if delay<0 (updated) + l->l: sleep(-delay);\ndelay=0 + note right + If delay is negative, we sleep + in the calling thread and + set delay=0 + end note + activate l + deactivate l +end + +end + +l->t: + + +@enduml \ No newline at end of file diff --git a/sort_docs/ratelimiter_timelines.puml b/sort_docs/ratelimiter_timelines.puml new file mode 100644 index 000000000..649d74a43 --- /dev/null +++ b/sort_docs/ratelimiter_timelines.puml @@ -0,0 +1,47 @@ +@startuml +scale 100 as 100 pixels + +Title Rate Limiter - **Timelines** + +robust "typical" as W1 +@W1 +0 is past +100 is allocated #yellow +200 is scheduled #lightgreen +632 is now #lightblue +W1@100 <-> @200: schedule\ndelay +W1@200 <-> @632: + +robust "no waittime" as W2 +@W2 +0 is past +200 is allocated #yellow +200.000001 is scheduled #lightgreen +632 is now #lightblue + +robust "caughtup" as W3 +@W3 +0 is past +100 is allocated #yellow +200.000001 is scheduled #lightgreen +232 is now #lightblue + +robust "ahead" as W4 +@W4 +0 is past +100 is allocated #yellow +200.000001 is scheduled #lightgreen +232 is now #lightblue + +concise "perfect ops" as O +@O +0 is op ++100 is op ++100 is op ++100 is op ++100 is op ++100 is op ++100 is op ++100 is op ++100 is op +@enduml diff --git a/sort_docs/research/multivariate.svg b/sort_docs/research/multivariate.svg new file mode 100644 index 000000000..a7f619f7a --- /dev/null +++ b/sort_docs/research/multivariate.svg @@ -0,0 +1,540 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + SCORE + value + throughput + latency + PARAMS + + + + + + + + + + + + + RESULT + ccph + async + threads + + + PARAMS + + + + + VALUE + + + + + + + + result + function + R(P) + value + function + V(R) + + V(R(P)) + + diff --git a/sort_docs/research/op_tracking.svg b/sort_docs/research/op_tracking.svg new file mode 100644 index 000000000..d46906623 --- /dev/null +++ b/sort_docs/research/op_tracking.svg @@ -0,0 +1,611 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + op + tracker + + + + + + + + + + scenario + + + + + + + activity + + + + input + + + + async + count + + + + stride + tracker + + + + cycle + segment + + + + + + + thread + + + diff --git a/sort_docs/testseq_early.png b/sort_docs/testseq_early.png new file mode 100644 index 0000000000000000000000000000000000000000..df14d6361284e87b5e337fc07679e527385965a9 GIT binary patch literal 25703 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 + +@E +500 is unseen #white +@500 <-> @732: **error** = 232 +A -> C + +@S +0 is idle #grey +100 is scheduled #orange +600 is unscheduled #white +@500 <-> @600: **scheduling_delay** =\nelapsed - scheduled = -100 + +@A +300 is unallocated #white +@300 <-> @500: **wait_time** =\nelapsed - allocated = 200 + +concise "Ops" as O +@O +0 is op ++100 is op ++100 is op ++100 is op ++100 is op ++100 is op ++100 is op ++100 is op ++100 is op +@enduml diff --git a/sort_docs/testseq_late.png b/sort_docs/testseq_late.png new file mode 100644 index 0000000000000000000000000000000000000000..95c894b08a83e6338079b754d2765b4fabd24b1f GIT binary patch literal 25478 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 C + +@632 +C is future #white +E->C + +@A +@100 <-> @500: **wait_time** =\nelapsed - allocated = 400 +@E +@500 <-> @632: **error** = 132 +@S +@200 <-> @500: **scheduling_delay** =\nelapsed - scheduled = 300 + +concise "Ops" as O +@O +0 is op ++100 is op ++100 is op ++100 is op ++100 is op ++100 is op ++100 is op ++100 is op ++100 is op +@enduml diff --git a/sort_docs/todo.md b/sort_docs/todo.md new file mode 100644 index 000000000..a173147ef --- /dev/null +++ b/sort_docs/todo.md @@ -0,0 +1,16 @@ +- convert core input to be equivalent + of `input=type:interval,cycles:N[..M]` +- Add doc support for input, input filters, outputs, output filters +- Build metadata scaffolding for parameters, so unused parameters may be + warned about. + - parameters should be part of the activity API + - parameters should not re-trigger def observers for non-change + evhandler + - parameters across all subsystems should be discoverable or + enumerable +- make stride auto-sizing uniformly apply after sequencing +- reimplement core activity and scenario logic as async/reactor with + monitors +- convert to Java 9 +- add activity library commands +- add --list-input-filters and --list-output-filters \ No newline at end of file