Skip to content

Commit 466aacd

Browse files
authored
Merge pull request #127 from SystemFw/adjustable
Adjustable controls
2 parents 022f8f5 + f2338e1 commit 466aacd

19 files changed

+848
-209
lines changed

.github/workflows/ci.yml

+20-16
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,21 @@ jobs:
2626
strategy:
2727
matrix:
2828
os: [ubuntu-latest]
29-
scala: [2.13.6, 3.0.0, 2.12.14]
30-
29+
scala: [2.13.6, 3.1.0, 2.12.14]
30+
java: [temurin@11]
3131
runs-on: ${{ matrix.os }}
3232
steps:
3333
- name: Checkout current branch (full)
3434
uses: actions/checkout@v2
3535
with:
3636
fetch-depth: 0
3737

38-
- name: Setup Java and Scala
39-
uses: olafurpg/setup-scala@v13
38+
- name: Setup Java (temurin@11)
39+
if: matrix.java == 'temurin@11'
40+
uses: actions/setup-java@v2
4041
with:
41-
java-version: ${{ matrix.java }}
42+
distribution: temurin
43+
java-version: 11
4244

4345
- name: Cache sbt
4446
uses: actions/cache@v2
@@ -77,18 +79,20 @@ jobs:
7779
matrix:
7880
os: [ubuntu-latest]
7981
scala: [2.13.6]
80-
82+
java: [temurin@11]
8183
runs-on: ${{ matrix.os }}
8284
steps:
8385
- name: Checkout current branch (full)
8486
uses: actions/checkout@v2
8587
with:
8688
fetch-depth: 0
8789

88-
- name: Setup Java and Scala
89-
uses: olafurpg/setup-scala@v13
90+
- name: Setup Java (temurin@11)
91+
if: matrix.java == 'temurin@11'
92+
uses: actions/setup-java@v2
9093
with:
91-
java-version: ${{ matrix.java }}
94+
distribution: temurin
95+
java-version: 11
9296

9397
- name: Cache sbt
9498
uses: actions/cache@v2
@@ -112,12 +116,12 @@ jobs:
112116
tar xf targets.tar
113117
rm targets.tar
114118
115-
- name: Download target directories (3.0.0)
119+
- name: Download target directories (3.1.0)
116120
uses: actions/download-artifact@v2
117121
with:
118-
name: target-${{ matrix.os }}-3.0.0-${{ matrix.java }}
122+
name: target-${{ matrix.os }}-3.1.0-${{ matrix.java }}
119123

120-
- name: Inflate target directories (3.0.0)
124+
- name: Inflate target directories (3.1.0)
121125
run: |
122126
tar xf targets.tar
123127
rm targets.tar
@@ -145,7 +149,7 @@ jobs:
145149
matrix:
146150
os: [ubuntu-latest]
147151
scala: [2.13.6]
148-
152+
java: [temurin@11]
149153
runs-on: ${{ matrix.os }}
150154
steps:
151155
- name: Download target directories (2.13.6)
@@ -158,12 +162,12 @@ jobs:
158162
tar xf targets.tar
159163
rm targets.tar
160164
161-
- name: Download target directories (3.0.0)
165+
- name: Download target directories (3.1.0)
162166
uses: actions/download-artifact@v2
163167
with:
164-
name: target-${{ matrix.os }}-3.0.0-${{ matrix.java }}
168+
name: target-${{ matrix.os }}-3.1.0-${{ matrix.java }}
165169

166-
- name: Inflate target directories (3.0.0)
170+
- name: Inflate target directories (3.1.0)
167171
run: |
168172
tar xf targets.tar
169173
rm targets.tar

build.sbt

+7-10
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,8 @@ Global / excludeLintKeys += scmInfo
1818
val Scala213 = "2.13.6"
1919
ThisBuild / spiewakMainBranches := Seq("main")
2020

21-
ThisBuild / crossScalaVersions := Seq(Scala213, "3.0.0", "2.12.14")
22-
ThisBuild / versionIntroduced := Map("3.0.0" -> "0.4.0")
21+
ThisBuild / crossScalaVersions := Seq(Scala213, "3.1.0", "2.12.14")
2322
ThisBuild / scalaVersion := (ThisBuild / crossScalaVersions).value.head
24-
Global / excludeLintKeys += versionIntroduced
2523
ThisBuild / initialCommands := """
2624
|import cats._, data._, syntax.all._
2725
|import cats.effect._, concurrent._
@@ -34,6 +32,7 @@ ThisBuild / initialCommands := """
3432
""".stripMargin
3533

3634
ThisBuild / testFrameworks += new TestFramework("munit.Framework")
35+
ThisBuild / Test / parallelExecution := false
3736

3837
def dep(org: String, prefix: String, version: String)(modules: String*)(testModules: String*) =
3938
modules.map(m => org %% (prefix ++ m) % version) ++
@@ -50,12 +49,12 @@ lazy val core = project
5049
name := "upperbound",
5150
scalafmtOnCompile := true,
5251
libraryDependencies ++=
53-
dep("org.typelevel", "cats-", "2.6.1")("core")() ++
54-
dep("org.typelevel", "cats-effect", "3.3-162-2022ef9")("")("-laws", "-testkit") ++
55-
dep("co.fs2", "fs2-", "3.1.3")("core")() ++
52+
dep("org.typelevel", "cats-", "2.7.0")("core")() ++
53+
dep("org.typelevel", "cats-effect", "3.3.1")("")("-laws", "-testkit") ++
54+
dep("co.fs2", "fs2-", "3.2.4")("core")() ++
5655
dep("org.scalameta", "munit", "0.7.29")()("", "-scalacheck") ++
57-
dep("org.typelevel", "", "1.0.5")()("munit-cats-effect-3") ++
58-
dep("org.typelevel", "scalacheck-effect", "1.0.2")()("", "-munit")
56+
dep("org.typelevel", "", "1.0.7")()("munit-cats-effect-3") ++
57+
dep("org.typelevel", "scalacheck-effect", "1.0.3")()("", "-munit")
5958
)
6059

6160
lazy val docs = project
@@ -75,8 +74,6 @@ lazy val docs = project
7574
.dependsOn(core)
7675
.enablePlugins(MdocPlugin, NoPublishPlugin)
7776

78-
ThisBuild / githubWorkflowJavaVersions := Seq("[email protected]")
79-
8077
ThisBuild / githubWorkflowBuildPostamble ++= List(
8178
WorkflowStep.Sbt(
8279
List("docs/mdoc"),

docs/_coverpage.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
- Interval-based design to prevent bursts
66
- Prioritised jobs
7-
- Controls both rate and concurrency
7+
- Dynamic controls over both rate and concurrency
88

99
[Getting started](installing.md)
1010

docs/_sidebar.md

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
- [Installing](installing.md)
22
- [Design](design.md)
33
- [Limiter](limiter.md)
4-
- [Migration guide](migration.md)

docs/design.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ It's intended as a simple, minimal library, but with enough control to
1010
be broadly applicable, including:
1111
- Job execution rate
1212
- Maximum concurrency of jobs
13+
- Dynamically adjustable rate and concurrency
1314
- Prioritisation of jobs
1415

1516
**upperbound** is a purely functional library, built on top of

docs/limiter.md

+37-4
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ new limiter and starts processing jobs submitted to it.
5252
object Limiter {
5353
def start[F[_]: Temporal](
5454
minInterval: FiniteDuration,
55-
maxQueued: Int = Int.MaxValue,
56-
maxConcurrent: Int = Int.MaxValue
55+
maxConcurrent: Int = Int.MaxValue,
56+
maxQueued: Int = Int.MaxValue
5757
): Resource[F, Limiter[F]]
5858
}
5959
```
@@ -174,13 +174,46 @@ limiter.use { limiter =>
174174
```
175175

176176
If you struggled to make sense of the examples in this section, it's
177-
recommended to watch [this
178-
talk](https://github.com/SystemFw/scala-italy-2018).
177+
recommended to watch [this talk](https://github.com/SystemFw/scala-italy-2018.)
179178

179+
## Adjusting rate and concurrency
180+
181+
**upperbound** lets you control both the rate of submission and the
182+
maximum concurrency dynamically, through the following methods on
183+
`Limiter`:
184+
185+
```scala
186+
def minInterval: F[FiniteDuration]
187+
def setMinInterval(newMinInterval: FiniteDuration): F[Unit]
188+
def updateMinInterval(update: FiniteDuration => FiniteDuration): F[Unit]
189+
190+
def maxConcurrent: F[Int]
191+
def setMaxConcurrent(newMaxConcurrent: Int): F[Unit]
192+
def updateMaxConcurrent(update: Int => Int): F[Unit]
193+
```
194+
195+
The `*minInterval` methods let you change the rate of submission by
196+
varying the minimum time interval between two tasks. If the interval
197+
changes while the limiter is sleeping between tasks, the duration of
198+
the sleep is adjusted on the fly, taking into account any elapsed
199+
time. This might mean waking up instantly if the entire new interval
200+
has already elapsed.
201+
202+
The `*maxConcurrent` methods let you change the maximum number of
203+
concurrent tasks that can be executing at any given time. If the
204+
concurrency limit gets changed while the limiter is already blocked
205+
waiting for some tasks to finish, the limiter will then be unblocked
206+
as soon as the number of running tasks goes below the new concurrency
207+
limit. Note however that if the limit shrinks the limiter will not try to
208+
interrupt tasks that are already running, so for some time it might be
209+
that `runningTasks > maxConcurrent`.
210+
211+
180212
## Test limiter
181213

182214
**upperbound** also provides `Limiter.noOp` for testing purposes, which is
183215
a stub `Limiter` with no actual rate limiting and a synchronous
184216
`submit` method.
185217

186218

219+

0 commit comments

Comments
 (0)