├── .github ├── dco.yml ├── dependabot.yml ├── release.yml └── workflows │ ├── pr-checks.yml │ └── publish.yml ├── .gitignore ├── README.md ├── build.gradle ├── docs └── api │ ├── overview.html │ └── stylesheet.css ├── gradle.properties ├── gradle ├── javadoc.gradle ├── libs.versions.toml ├── releaser.gradle ├── setup.gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── reactor-adapter └── src │ ├── main │ └── java │ │ └── reactor │ │ └── adapter │ │ ├── akka │ │ └── ActorScheduler.java │ │ └── rxjava │ │ ├── RxJava2Adapter.java │ │ ├── RxJava2Scheduler.java │ │ ├── RxJava2Schedulers.java │ │ ├── RxJava3Adapter.java │ │ ├── RxJava3Scheduler.java │ │ └── package-info.java │ └── test │ ├── java │ └── reactor │ │ └── adapter │ │ ├── akka │ │ └── ActorAdapterTest.java │ │ └── rxjava │ │ ├── RxJava2AdapterTest.java │ │ ├── RxJava2SchedulersTest.java │ │ └── RxJava3AdapterTest.java │ └── resources │ └── akka-streams.conf ├── reactor-extra └── src │ ├── main │ └── java │ │ └── reactor │ │ ├── bool │ │ └── BooleanUtils.java │ │ ├── cache │ │ ├── CacheFlux.java │ │ ├── CacheMono.java │ │ └── package-info.java │ │ ├── function │ │ ├── Consumer3.java │ │ ├── Consumer4.java │ │ ├── Consumer5.java │ │ ├── Consumer6.java │ │ ├── Consumer7.java │ │ ├── Consumer8.java │ │ ├── Function3.java │ │ ├── Function4.java │ │ ├── Function5.java │ │ ├── Function6.java │ │ ├── Function7.java │ │ ├── Function8.java │ │ ├── Predicate3.java │ │ ├── Predicate4.java │ │ ├── Predicate5.java │ │ ├── Predicate6.java │ │ ├── Predicate7.java │ │ ├── Predicate8.java │ │ └── TupleUtils.java │ │ ├── math │ │ ├── MathFlux.java │ │ ├── MathSubscriber.java │ │ ├── MonoAverageBigDecimal.java │ │ ├── MonoAverageBigInteger.java │ │ ├── MonoAverageDouble.java │ │ ├── MonoAverageFloat.java │ │ ├── MonoFromFluxOperator.java │ │ ├── MonoMinMax.java │ │ ├── MonoSumBigDecimal.java │ │ ├── MonoSumBigInteger.java │ │ ├── MonoSumDouble.java │ │ ├── MonoSumFloat.java │ │ ├── MonoSumInt.java │ │ └── MonoSumLong.java │ │ ├── retry │ │ ├── AbstractRetry.java │ │ ├── Backoff.java │ │ ├── BackoffDelay.java │ │ ├── DefaultContext.java │ │ ├── DefaultRepeat.java │ │ ├── DefaultRetry.java │ │ ├── IterationContext.java │ │ ├── Jitter.java │ │ ├── RandomJitter.java │ │ ├── Repeat.java │ │ ├── RepeatContext.java │ │ ├── Retry.java │ │ ├── RetryContext.java │ │ └── RetryExhaustedException.java │ │ ├── scheduler │ │ ├── clock │ │ │ └── SchedulerClock.java │ │ └── forkjoin │ │ │ └── ForkJoinPoolScheduler.java │ │ └── swing │ │ ├── SwingScheduler.java │ │ └── SwtScheduler.java │ └── test │ └── java │ └── reactor │ ├── bool │ └── BooleanUtilsTest.java │ ├── cache │ ├── CacheFluxTest.java │ └── CacheMonoTest.java │ ├── function │ └── TupleUtilsTest.java │ ├── math │ └── ReactorMathTests.java │ ├── retry │ ├── AbstractRetryTest.java │ ├── BackoffDelayTest.java │ ├── BackoffTest.java │ ├── DefaultRepeatTest.java │ ├── DefaultRetryTest.java │ ├── RandomJitterTest.java │ ├── RepeatTests.java │ ├── RetryTestUtils.java │ └── RetryTests.java │ ├── scheduler │ ├── clock │ │ └── SchedulerClockTest.java │ └── forkjoin │ │ ├── AbstractSchedulerTest.java │ │ └── ForkJoinPoolSchedulerTest.java │ └── swing │ ├── SwingAdapterTest.java │ └── SwtAdapterTest.java └── settings.gradle /.github/dco.yml: -------------------------------------------------------------------------------- 1 | require: 2 | members: false 3 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: gradle 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 10 8 | assignees: 9 | - violetagg 10 | target-branch: "3.5.x" 11 | labels: 12 | - type/dependency-upgrade 13 | ignore: 14 | # Don't update Reactor projects 15 | - dependency-name: io.projectreactor:* 16 | # JSR305 backport is fixed to last version with annotations (3.0.1) 17 | - dependency-name: "com.google.code.findbugs:jsr305" 18 | # Versions > 4 require JDK11+ 19 | - dependency-name: org.mockito:mockito-core 20 | versions: 21 | - "[5.a, 6]" 22 | # Versions > 6 require JDK17+ 23 | - dependency-name: biz.aQute.bnd.builder 24 | versions: 25 | - "[7.a, 8]" 26 | - dependency-name: org.slf4j:* 27 | versions: 28 | - "[2.a, 3]" 29 | - dependency-name: ch.qos.logback:logback-classic 30 | versions: 31 | - "[1.3.a, 1.6]" 32 | # artifactory: don't upgrade to v5 33 | - dependency-name: "com.jfrog.artifactory" 34 | versions: 35 | - ">= 5.0.a" 36 | # TestNG: 7.6+ doesn't support JDK8 anymore 37 | - dependency-name: "org.testng:testng" 38 | versions: 39 | - ">= 7.6.a" 40 | rebase-strategy: disabled 41 | - package-ecosystem: github-actions 42 | directory: "/" 43 | schedule: 44 | interval: daily 45 | open-pull-requests-limit: 10 46 | assignees: 47 | - violetagg 48 | target-branch: "3.5.x" 49 | labels: 50 | - type/dependency-upgrade 51 | rebase-strategy: disabled 52 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | changelog: 2 | exclude: 3 | labels: 4 | - ignore-changelog 5 | - type/chore 6 | - type/dependency-upgrade 7 | categories: 8 | - title: ":warning: Update considerations and deprecations" 9 | labels: 10 | - "warn/api-change" 11 | - "warn/behavior-change" 12 | - "warn/blocker" 13 | - "warn/deprecation" 14 | - "warn/regression" 15 | - title: ":sparkles: New features and improvements" 16 | labels: 17 | - "type/enhancement" 18 | - title: ":lady_beetle: Bug fixes" 19 | labels: 20 | - "type/bug" 21 | - title: ":book: Documentation" 22 | labels: 23 | - "type/documentation" 24 | - title: ":question: Other Changes" 25 | labels: 26 | - "*" 27 | -------------------------------------------------------------------------------- /.github/workflows/pr-checks.yml: -------------------------------------------------------------------------------- 1 | name: PR Checks 2 | on: 3 | pull_request: {} 4 | permissions: read-all 5 | jobs: 6 | checks: 7 | name: checks 8 | runs-on: ubuntu-22.04 9 | steps: 10 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 11 | - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 12 | with: 13 | distribution: 'temurin' 14 | java-version: 8 15 | - name: Setup Gradle 16 | uses: gradle/actions/setup-gradle@8379f6a1328ee0e06e2bb424dadb7b159856a326 17 | - name: gradle 18 | run: ./gradlew check javadoc 19 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: publish 2 | on: 3 | push: 4 | branches: # For branches, better to list them explicitly than regexp include 5 | - main 6 | - 3.5.x 7 | - 3.4.x 8 | permissions: read-all 9 | jobs: 10 | # General job notes: we DON'T want to cancel any previous runs, especially in the case of a "back to snapshots" build right after a release push 11 | # We specify the ubuntu version to minimize the chances we have to deal with a migration during a release 12 | prepare: 13 | # Notes on prepare: this job has no access to secrets, only github token. As a result, all non-core actions are centralized here 14 | # This includes the tagging and drafting of release notes. Still, when possible we favor plain run of gradle tasks 15 | name: prepare 16 | runs-on: ubuntu-22.04 17 | outputs: 18 | versionType: ${{ steps.version.outputs.versionType }} 19 | fullVersion: ${{ steps.version.outputs.fullVersion }} 20 | steps: 21 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 22 | - name: setup java 23 | uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # tag=v3 24 | with: 25 | distribution: 'temurin' 26 | java-version: 8 27 | - name: interpret version 28 | id: version 29 | #we only run the qualifyVersionGha task so that no other console printing can hijack this step's output 30 | #output: versionType, fullVersion 31 | #fails if versionType is BAD, which interrupts the workflow 32 | run: ./gradlew qualifyVersionGha 33 | - name: run checks 34 | id: checks 35 | run: ./gradlew check 36 | 37 | #deploy the snapshot artifacts to Artifactory 38 | deploySnapshot: 39 | name: deploySnapshot 40 | runs-on: ubuntu-22.04 41 | needs: prepare 42 | if: needs.prepare.outputs.versionType == 'SNAPSHOT' 43 | environment: snapshots 44 | steps: 45 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 46 | - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # tag=v3 47 | with: 48 | distribution: 'temurin' 49 | java-version: 8 50 | - name: deploy 51 | env: 52 | ORG_GRADLE_PROJECT_artifactory_publish_username: ${{secrets.ARTIFACTORY_SNAPSHOT_USERNAME}} 53 | ORG_GRADLE_PROJECT_artifactory_publish_password: ${{secrets.ARTIFACTORY_PASSWORD}} 54 | run: | 55 | ./gradlew assemble artifactoryPublish -Partifactory_publish_contextUrl=https://repo.spring.io -Partifactory_publish_repoKey=libs-snapshot-local 56 | 57 | #sign the milestone artifacts and deploy them to Artifactory 58 | deployMilestone: 59 | name: deployMilestone 60 | runs-on: ubuntu-22.04 61 | needs: prepare 62 | if: needs.prepare.outputs.versionType == 'MILESTONE' 63 | environment: releases 64 | steps: 65 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 66 | - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # tag=v3 67 | with: 68 | distribution: 'temurin' 69 | java-version: 8 70 | - name: deploy 71 | env: 72 | ORG_GRADLE_PROJECT_artifactory_publish_username: ${{secrets.ARTIFACTORY_USERNAME}} 73 | ORG_GRADLE_PROJECT_artifactory_publish_password: ${{secrets.ARTIFACTORY_PASSWORD}} 74 | ORG_GRADLE_PROJECT_signingKey: ${{secrets.SIGNING_KEY}} 75 | ORG_GRADLE_PROJECT_signingPassword: ${{secrets.SIGNING_PASSPHRASE}} 76 | run: | 77 | ./gradlew assemble sign artifactoryPublish -Partifactory_publish_contextUrl=https://repo.spring.io -Partifactory_publish_repoKey=libs-milestone-local 78 | 79 | #sign the release artifacts and deploy them to Artifactory 80 | deployRelease: 81 | name: deployRelease 82 | runs-on: ubuntu-22.04 83 | needs: prepare 84 | if: needs.prepare.outputs.versionType == 'RELEASE' 85 | environment: releases 86 | steps: 87 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 88 | - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # tag=v3 89 | with: 90 | distribution: 'temurin' 91 | java-version: 8 92 | - name: deploy 93 | env: 94 | ORG_GRADLE_PROJECT_artifactory_publish_username: ${{secrets.ARTIFACTORY_USERNAME}} 95 | ORG_GRADLE_PROJECT_artifactory_publish_password: ${{secrets.ARTIFACTORY_PASSWORD}} 96 | ORG_GRADLE_PROJECT_signingKey: ${{secrets.SIGNING_KEY}} 97 | ORG_GRADLE_PROJECT_signingPassword: ${{secrets.SIGNING_PASSPHRASE}} 98 | ORG_GRADLE_PROJECT_sonatypeUsername: ${{secrets.SONATYPE_USERNAME}} 99 | ORG_GRADLE_PROJECT_sonatypePassword: ${{secrets.SONATYPE_PASSWORD}} 100 | run: | 101 | ./gradlew assemble sign artifactoryPublish -Partifactory_publish_contextUrl=https://repo.spring.io -Partifactory_publish_repoKey=libs-release-local publishMavenJavaPublicationToSonatypeRepository 102 | - name: Stage the release 103 | env: 104 | ORG_GRADLE_PROJECT_sonatypeUsername: ${{secrets.SONATYPE_USERNAME}} 105 | ORG_GRADLE_PROJECT_sonatypePassword: ${{secrets.SONATYPE_PASSWORD}} 106 | run: | 107 | GRADLE_PUBLISH_MAVEN_AUTHORIZATION=$(echo "${ORG_GRADLE_PROJECT_sonatypeUsername}:${ORG_GRADLE_PROJECT_sonatypePassword}" | base64) 108 | echo "Searching for opened repository..." 109 | REPOSITORY_RESPONSE=$(curl -s -X GET \ 110 | -H "Authorization: Bearer ${GRADLE_PUBLISH_MAVEN_AUTHORIZATION}" \ 111 | "https://ossrh-staging-api.central.sonatype.com/manual/search/repositories?state=open") 112 | REPOSITORY_KEY=$(echo "${REPOSITORY_RESPONSE}" | grep -o '"key":"[^"]*"' | head -1 | cut -d':' -f2 | tr -d '"') 113 | echo "Triggering uploading..." 114 | curl -s -X POST \ 115 | -H "Authorization: Bearer ${GRADLE_PUBLISH_MAVEN_AUTHORIZATION}" \ 116 | "https://ossrh-staging-api.central.sonatype.com/manual/upload/repository/${REPOSITORY_KEY}?publishing_type=user_managed" 117 | 118 | tagMilestone: 119 | name: Tag milestone 120 | needs: [ prepare, deployMilestone ] 121 | runs-on: ubuntu-22.04 122 | permissions: 123 | contents: write 124 | steps: 125 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 126 | - name: tag 127 | run: | 128 | git config --local user.name 'reactorbot' 129 | git config --local user.email '32325210+reactorbot@users.noreply.github.com' 130 | git tag -m "Release milestone ${{ needs.prepare.outputs.fullVersion }}" v${{ needs.prepare.outputs.fullVersion }} ${{ github.sha }} 131 | git push --tags 132 | 133 | tagRelease: 134 | name: Tag release 135 | needs: [ prepare, deployRelease ] 136 | runs-on: ubuntu-22.04 137 | permissions: 138 | contents: write 139 | steps: 140 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 141 | - name: tag 142 | run: | 143 | git config --local user.name 'reactorbot' 144 | git config --local user.email '32325210+reactorbot@users.noreply.github.com' 145 | git tag -m "Release version ${{ needs.prepare.outputs.fullVersion }}" v${{ needs.prepare.outputs.fullVersion }} ${{ github.sha }} 146 | git push --tags 147 | 148 | # For Gradle configuration of signing, see https://docs.gradle.org/current/userguide/signing_plugin.html#sec:in-memory-keys 149 | # publishMavenJavaPublicationToSonatypeRepository only sends to a staging repository -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | reactor-pylon/src/main/resources/public 3 | .DS_Store 4 | bin 5 | build 6 | .classpath 7 | .eclipse 8 | .gradle 9 | .project 10 | .settings 11 | out 12 | *.log 13 | .sass-cache 14 | *.i* 15 | *.java.hsp 16 | deps.txt 17 | line_feed.txt 18 | *.index 19 | *.data 20 | classes 21 | exportToHtml 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Reactor Addons 2 | 3 | [](https://github.com/reactor/reactor-addons/actions/workflows/publish.yml) 4 | 5 | [](https://gitter.im/reactor/reactor?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 6 | 7 | [](https://mvnrepository.com/artifact/io.projectreactor.addons/reactor-extra) 8 | 9 | # Addons List 10 | 11 | # reactor-adapter 12 | 13 | Bridge to RxJava 2 Observable, Completable, Flowable, Single, Maybe, Scheduler, and also SWT Scheduler, Akka Scheduler ... 14 | 15 | # reactor-extra 16 | 17 | Extra operations and processors for Reactor Core including mathematical operations to compute sum, average, min or max from numerical sources. 18 | 19 | # Contributing an Add-on 20 | 21 | ### Build instructions 22 | 23 | `Reactor` uses a Gradle-based build system. Building the code yourself should be a straightforward case of: 24 | 25 | git clone git@github.com:reactor/reactor-addons.git 26 | cd reactor-addons 27 | ./gradlew test 28 | 29 | This should cause the submodules to be compiled and the tests to be run. To install these artifacts to your local Maven repo, use the handly Gradle Maven plugin: 30 | 31 | ./gradlew install 32 | 33 | ### Maven Artifacts 34 | 35 | Snapshot and pre-release Maven artifacts are provided in the SpringSource snapshot repositories. 36 | To add this repo to your Gradle build, specify the URL like the following: 37 | 38 | ext { 39 | reactorAddonsVersion = '3.6.0-RC1' 40 | } 41 | 42 | repositories { 43 | //maven { url 'https://repo.spring.io/release' } 44 | maven { url 'https://repo.spring.io/milestone' } 45 | //maven { url 'https://repo.spring.io/snapshot' } 46 | mavenCentral() 47 | } 48 | 49 | dependencies { 50 | // Reactor Adapter (RxJava2, Akka Actors scheduler and more) 51 | compile "io.projectreactor.addons:reactor-adapter:$reactorAddonsVersion" 52 | } 53 | 54 | 55 | ## Documentation 56 | 57 | * [Guides](https://projectreactor.io/docs) (Notably `reactor-core` reference guide which 58 | contains a section [about testing](https://projectreactor.io/docs/core/release/reference/docs/index.html#testing)) 59 | * [Reactive Streams](https://www.reactive-streams.org/) 60 | 61 | ## Community / Support 62 | 63 | * [GitHub Issues](https://github.com/reactor/reactor-addons/issues) 64 | 65 | ## License 66 | 67 | Reactor is [Apache 2.0 licensed](https://www.apache.org/licenses/LICENSE-2.0.html). 68 | -------------------------------------------------------------------------------- /docs/api/overview.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |firstBackoff * (factor ** n)
where n is the iteration. If
72 | * maxBackoff
is not null, the maximum backoff applied will be limited to
73 | * maxBackoff
.
74 | *
75 | * If basedOnPreviousValue
is true, backoff will be calculated using
76 | * prevBackoff * factor
. When backoffs are combined with {@link Jitter}, this
77 | * value will be different from the actual exponential value for the iteration.
78 | *
79 | * @param firstBackoff First backoff duration
80 | * @param maxBackoff Maximum backoff duration, capped to {@link Long#MAX_VALUE} milliseconds
81 | * @param factor The multiplicand for calculating backoff
82 | * @param basedOnPreviousValue If true, calculation is based on previous value which may
83 | * be a backoff with jitter applied
84 | * @return Backoff function with exponential delay
85 | */
86 | static Backoff exponential(Duration firstBackoff, @Nullable Duration maxBackoff, int factor, boolean basedOnPreviousValue) {
87 | if (firstBackoff == null || firstBackoff.isNegative() || firstBackoff.isZero())
88 | throw new IllegalArgumentException("firstBackoff must be > 0");
89 | Duration cap = Duration.ofMillis(Long.MAX_VALUE);
90 | if (maxBackoff != null && maxBackoff.compareTo(cap) > 0) {
91 | throw new IllegalArgumentException("maxBackoff must be less than Long.MAX_VALUE milliseconds");
92 | }
93 | Duration maxBackoffInterval = maxBackoff != null && maxBackoff.compareTo(cap) < 0 ? maxBackoff : cap;
94 | if (maxBackoffInterval.compareTo(firstBackoff) < 0)
95 | throw new IllegalArgumentException("maxBackoff must be >= firstBackoff");
96 | if (!basedOnPreviousValue) {
97 | return new Backoff() {
98 | @Override
99 | public BackoffDelay apply(IterationContext> context) {
100 | Duration nextBackoff;
101 | if (context.backoff() != null && context.backoff().compareTo(maxBackoffInterval) >= 0) {
102 | nextBackoff = maxBackoffInterval;
103 | }
104 | else {
105 | try {
106 | nextBackoff = firstBackoff.multipliedBy((long) Math.pow(factor, (context.iteration() - 1)));
107 | if (nextBackoff.compareTo(maxBackoffInterval) >= 0) {
108 | nextBackoff = maxBackoffInterval;
109 | }
110 | }
111 | catch (ArithmeticException e) {
112 | nextBackoff = maxBackoffInterval;
113 | }
114 | }
115 | return new BackoffDelay(firstBackoff, maxBackoffInterval, nextBackoff);
116 | }
117 |
118 | @Override
119 | public String toString() {
120 | return String.format("Backoff{exponential,min=%sms,max=%s,factor=%s,basedOnPreviousValue=false}",
121 | firstBackoff.toMillis(),
122 | maxBackoff == null ? "NONE" : maxBackoff.toMillis() + "ms",
123 | factor);
124 | }
125 | };
126 | }
127 | else {
128 | return new Backoff() {
129 | @Override
130 | public BackoffDelay apply(IterationContext> context) {
131 | Duration prevBackoff = context.backoff() == null ? Duration.ZERO : context.backoff();
132 | Duration nextBackoff;
133 | if (prevBackoff.compareTo(maxBackoffInterval) >= 0) {
134 | nextBackoff = maxBackoffInterval;
135 | }
136 | else try {
137 | nextBackoff = prevBackoff.multipliedBy(factor);
138 | if (nextBackoff.compareTo(maxBackoffInterval) >= 0) {
139 | nextBackoff = maxBackoffInterval;
140 | }
141 | }
142 | catch (ArithmeticException e) {
143 | nextBackoff = maxBackoffInterval;
144 | }
145 | nextBackoff = nextBackoff.compareTo(firstBackoff) < 0 ? firstBackoff : nextBackoff;
146 | return new BackoffDelay(firstBackoff, maxBackoffInterval, nextBackoff);
147 | }
148 |
149 | @Override
150 | public String toString() {
151 | return String.format("Backoff{exponential,min=%sms,max=%s,factor=%s,basedOnPreviousValue=true}",
152 | firstBackoff.toMillis(),
153 | maxBackoff == null ? "NONE" : maxBackoff.toMillis() + "ms",
154 | factor);
155 | }
156 | };
157 | }
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/reactor-extra/src/main/java/reactor/retry/BackoffDelay.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021 VMware Inc. or its affiliates, All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package reactor.retry;
18 |
19 | import java.time.Duration;
20 |
21 | public class BackoffDelay {
22 |
23 | static final BackoffDelay ZERO = new BackoffDelay(Duration.ZERO) {
24 | @Override
25 | public String toString() {
26 | return "{ZERO}";
27 | }
28 | };
29 |
30 | final Duration min;
31 | final Duration max;
32 | final Duration delay;
33 |
34 | public BackoffDelay(Duration fixedBackoff) {
35 | this(fixedBackoff, fixedBackoff, fixedBackoff);
36 | }
37 |
38 | public BackoffDelay(Duration min, Duration max, Duration delay) {
39 | this.min = min;
40 | this.max = max;
41 | this.delay = delay;
42 | }
43 |
44 | public Duration minDelay() {
45 | return min;
46 | }
47 |
48 | public Duration maxDelay() {
49 | return max;
50 | }
51 |
52 | public Duration delay() {
53 | return delay;
54 | }
55 |
56 | @Override
57 | public String toString() {
58 | if (min == max && max == delay) {
59 | return "{" + delay.toMillis() + "ms}";
60 | }
61 | else {
62 | return "{" + delay.toMillis() + "ms/" + max.toMillis() + "ms}";
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/reactor-extra/src/main/java/reactor/retry/DefaultContext.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2021 VMware Inc. or its affiliates, All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package reactor.retry;
18 |
19 | import java.time.Duration;
20 |
21 | public class DefaultContext