Skip to content

Commit 7b232c6

Browse files
committed
Release 0.5.8
1 parent 52e250b commit 7b232c6

File tree

8 files changed

+32
-20
lines changed

8 files changed

+32
-20
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ the project!
2323
To test Ox, use the following dependency, using either [sbt](https://www.scala-sbt.org):
2424

2525
```scala
26-
"com.softwaremill.ox" %% "core" % "0.5.7"
26+
"com.softwaremill.ox" %% "core" % "0.5.8"
2727
```
2828

2929
Or [scala-cli](https://scala-cli.virtuslab.org):
3030

3131
```scala
32-
//> using dep "com.softwaremill.ox::core:0.5.7"
32+
//> using dep "com.softwaremill.ox::core:0.5.8"
3333
```
3434

3535
Documentation is available at [https://ox.softwaremill.com](https://ox.softwaremill.com), ScalaDocs can be browsed at [https://javadoc.io](https://www.javadoc.io/doc/com.softwaremill.ox).

generated-doc/out/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Safe direct-style concurrency and resiliency for Scala on the JVM. Requires JDK 21 & Scala 3.
44

5-
To start using Ox, add the `com.softwaremill.ox::core:0.5.7` [dependency](info/dependency.md) to your project.
5+
To start using Ox, add the `com.softwaremill.ox::core:0.5.8` [dependency](info/dependency.md) to your project.
66
Then, take a look at the tour of Ox, or follow one of the topics listed in the menu to get to know Ox's API!
77

88
In addition to this documentation, ScalaDocs can be browsed at [https://javadoc.io](https://www.javadoc.io/doc/com.softwaremill.ox).

generated-doc/out/info/dependency.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ To use ox core in your project, add:
44

55
```scala
66
// sbt dependency
7-
"com.softwaremill.ox" %% "core" % "0.5.7"
7+
"com.softwaremill.ox" %% "core" % "0.5.8"
88

99
// scala-cli dependency
10-
//> using dep com.softwaremill.ox::core:0.5.7
10+
//> using dep com.softwaremill.ox::core:0.5.8
1111
```
1212

1313
Ox core depends only on the Java [jox](https://github.com/softwaremill/jox) project, where channels are implemented. There are no other direct or transitive dependencies.

generated-doc/out/integrations/kafka.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Dependency:
44

55
```scala
6-
"com.softwaremill.ox" %% "kafka" % "0.5.7"
6+
"com.softwaremill.ox" %% "kafka" % "0.5.8"
77
```
88

99
`Flow`s which read from a Kafka topic, mapping stages and drains which publish to Kafka topics are available through

generated-doc/out/integrations/mdc-logback.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Dependency:
44

55
```scala
6-
"com.softwaremill.ox" %% "mdc-logback" % "0.5.7"
6+
"com.softwaremill.ox" %% "mdc-logback" % "0.5.8"
77
```
88

99
Ox provides support for setting inheritable MDC (mapped diagnostic context) values, when using the [Logback](https://logback.qos.ch)

generated-doc/out/streaming/flows.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ To obtain a `org.reactivestreams.Publisher` instance, you'll need to add the fol
171171
bring the `toReactiveStreamsPublisher` method into scope:
172172

173173
```scala
174-
// sbt dependency: "com.softwaremill.ox" %% "flow-reactive-streams" % "0.5.7"
174+
// sbt dependency: "com.softwaremill.ox" %% "flow-reactive-streams" % "0.5.8"
175175

176176
import ox.supervised
177177
import ox.flow.Flow

generated-doc/out/tour.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ def computationR: Int = ???
6666
repeat(RepeatConfig.fixedRateForever(100.millis))(computationR)
6767
```
6868

69+
[Rate limit](utils/rate-limiter.md) computations:
70+
71+
```scala
72+
supervised:
73+
val rateLimiter = RateLimiter.fixedWindowWithStartTime(2, 1.second)
74+
rateLimiter.runBlocking({ /* ... */ })
75+
```
76+
6977
Allocate a [resource](utils/resources.md) in a scope:
7078

7179
```scala

generated-doc/out/utils/rate-limiter.md

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Rate limiter
22

3-
The rate limiter mechanism allows controlling the rate at which operations are executed. It ensures that at most a certain number of operations are run concurrently within a specified time frame, preventing system overload and ensuring fair resource usage. Note that the implemented limiting mechanism only takes into account the start of execution and not the whole execution of an operation.
3+
The rate limiter mechanism allows controlling the rate at which operations are executed. It ensures that at most a certain number of operations are run concurrently within a specified time frame, preventing system overload and ensuring fair resource usage.
4+
5+
Several rate limiting algorithms are available, either taking into account only the start time of the operation, or the entire duration of its execution.
46

57
## API
68

@@ -11,10 +13,8 @@ import ox.supervised
1113
import ox.resilience.*
1214
import scala.concurrent.duration.*
1315

14-
val algorithm = RateLimiterAlgorithm.FixedWindow(2, 1.second)
15-
1616
supervised:
17-
val rateLimiter = RateLimiter(algorithm)
17+
val rateLimiter = RateLimiter.fixedWindowWithStartTime(2, 1.second)
1818

1919
type T
2020
def operation: T = ???
@@ -34,24 +34,28 @@ The `operation` can be provided directly using a by-name parameter, i.e. `f: =>
3434
## Configuration
3535

3636
The configuration of a `RateLimiter` depends on an underlying algorithm that controls whether an operation can be executed or not. The following algorithms are available:
37-
- `RateLimiterAlgorithm.FixedWindow(rate: Int, dur: FiniteDuration)` - where `rate` is the maximum number of operations to be executed in fixed windows of `dur` duration.
38-
- `RateLimiterAlgorithm.SlidingWindow(rate: Int, dur: FiniteDuration)` - where `rate` is the maximum number of operations to be executed in any window of time of duration `dur`.
39-
- `RateLimiterAlgorithm.Bucket(maximum: Int, dur: FiniteDuration)` - where `maximum` is the maximum capacity of tokens available in the token bucket algorithm and one token is added each `dur`. It can represent both the leaky bucket algorithm or the token bucket algorithm.
37+
- `StartTimeRateLimiterAlgorithm.FixedWindow(rate: Int, per: FiniteDuration)` - where `rate` is the maximum number of operations to be executed in fixed windows of `per` duration.
38+
- `StartTimeRateLimiterAlgorithm.SlidingWindow(rate: Int, per: FiniteDuration)` - where `rate` is the maximum number of operations to be executed in any window of time of duration `per`.
39+
- `StartTimeRateLimiterAlgorithm.LeakyBucket(maximum: Int, per: FiniteDuration)` - where `rate` is the maximum capacity of tokens available in the token bucket algorithm and one token is added each `per`. It can represent both the leaky bucket algorithm or the token bucket algorithm.
40+
- `DurationRateLimiterAlgorithm.FixedWindow(rate: Int, per: FiniteDuration)` - where `rate` is the maximum number of operations which execution spans fixed windows of `per` duration. Considers whole execution time of an operation. Operation spanning more than one window blocks permits in all windows that it spans.
41+
- `DurationRateLimiterAlgorithm.SlidingWindow(rate: Int, per: FiniteDuration)` - where `rate` is the maximum number of operations which execution spans any window of time of duration `per`. Considers whole execution time of an operation. Operation release permit after `per` passed since operation ended.
4042

4143
### API shorthands
4244

4345
You can use one of the following shorthands to define a Rate Limiter with the corresponding algorithm:
4446

45-
- `RateLimiter.fixedWindow(rate: Int, dur: FiniteDuration)`,
46-
- `RateLimiter.slidingWindow(rate: Int, dur: FiniteDuration)`,
47-
- `RateLimiter.leakyBucket(maximum: Int, dur: FiniteDuration)`,
47+
- `RateLimiter.fixedWindowWithStartTime(maxOperations: Int, window: FiniteDuration)`
48+
- `RateLimiter.slidingWindowWithStartTime(maxOperations: Int, window: FiniteDuration)`
49+
- `RateLimiter.leakyBucket(maxTokens: Int, refillInterval: FiniteDuration)`
50+
- `RateLimiter.fixedWindowWithDuration(maxOperations: Int, window: FiniteDuration)`
51+
- `RateLimiter.slidingWindowWithDuration(maxOperations: Int, window: FiniteDuration)`
4852

4953
See the tests in `ox.resilience.*` for more.
5054

5155
## Custom rate limiter algorithms
5256

53-
The `RateLimiterAlgorithm` employed by `RateLimiter` can be extended to implement new algorithms or modify existing ones. Its interface is modelled like that of a `Semaphore` although the underlying implementation could be different. For best compatibility with the existing interface of `RateLimiter`, methods `acquire` and `tryAcquire` should offer the same guaranties as Java's `Semaphores`.
57+
The `RateLimiterAlgorithm` employed by `RateLimiter` can be extended to implement new algorithms or modify existing ones. Its interface is modelled like that of a `Semaphore` although the underlying implementation could be different. For best compatibility with the existing interface of `RateLimiter`, methods `acquire` and `tryAcquire` should offer the same guaranties as Java's `Semaphores`. There is also method `def runOperation[T](operation: => T, permits: Int): T` for cases where considering span of execution may be necessary (see implementations in `DurationRateLimiterAlgorithm`).
5458

55-
Additionally, there are two methods employed by the `GenericRateLimiter` for updating its internal state automatically:
59+
Additionally, there are two methods employed by the `RateLimiter` for updating its internal state automatically:
5660
- `def update(): Unit`: Updates the internal state of the rate limiter to reflect its current situation. Invoked in a background fork repeatedly, when a rate limiter is created.
5761
- `def getNextUpdate: Long`: Returns the time in nanoseconds after which a new `update` needs to be called.

0 commit comments

Comments
 (0)