Adjustments in availability determination:

- now isAvailable return true in case upstreams are OK or LAGGING
- All upstreams in Filtered API now sorted by status
This commit is contained in:
a10zn8
2023-02-13 18:48:01 +04:00
parent 1b83e99cff
commit 6d78b4927d
3 changed files with 38 additions and 4 deletions

View File

@@ -65,7 +65,7 @@ abstract class DefaultUpstream(
}
override fun isAvailable(): Boolean {
return getStatus() == UpstreamAvailability.OK
return getStatus() == UpstreamAvailability.OK || getStatus() == UpstreamAvailability.LAGGING
}
fun onStatus(value: BlockchainOuterClass.ChainStatus) {

View File

@@ -160,11 +160,11 @@ class FilteredApis(
override fun subscribe(subscriber: Subscriber<in Upstream>) {
// initially try only standard upstreams
val first = Flux.fromIterable(primaryUpstreams)
val second = Flux.fromIterable(secondaryUpstreams)
val first = Flux.fromIterable(primaryUpstreams.sortedBy { it.getStatus().grpcId })
val second = Flux.fromIterable(secondaryUpstreams.sortedBy { it.getStatus().grpcId })
// if all failed, try both standard and fallback upstreams, repeating in cycle
val retries = (0 until (retryLimit - 1)).map { r ->
Flux.fromIterable(standardWithFallback)
Flux.fromIterable(standardWithFallback.sortedBy { it.getStatus().grpcId })
// add a delay to let upstream to restore if it's a temp failure
// but delay only start of the check, not between upstreams
// i.e. if all upstreams failed -> wait -> check all without waiting in between

View File

@@ -227,6 +227,7 @@ class FilteredApisSpec extends Specification {
Mock(Upstream) {
_ * getRole() >> UpstreamsConfig.UpstreamRole.FALLBACK
_ * isAvailable() >> true
_ * getStatus() >> UpstreamAvailability.OK
}
]
when:
@@ -259,12 +260,14 @@ class FilteredApisSpec extends Specification {
Mock([name: "fallback"], Upstream) {
_ * getRole() >> UpstreamsConfig.UpstreamRole.FALLBACK
_ * isAvailable() >> true
_ * getStatus() >> UpstreamAvailability.OK
}
]
List<Upstream> secondary = [
Mock([name: "secondary"], Upstream) {
_ * getRole() >> UpstreamsConfig.UpstreamRole.SECONDARY
_ * isAvailable() >> true
_ * getStatus() >> UpstreamAvailability.OK
}
]
when:
@@ -287,4 +290,35 @@ class FilteredApisSpec extends Specification {
.expectComplete()
.verify(Duration.ofSeconds(1))
}
def "Use LAGGING after OK"() {
setup:
List<Upstream> lagging = [
Mock([name: "lagging"], Upstream) {
_ * getRole() >> UpstreamsConfig.UpstreamRole.PRIMARY
_ * isAvailable() >> true
_ * getStatus() >> UpstreamAvailability.LAGGING
}
]
List<Upstream> ok = [
Mock([name: "ok"], Upstream) {
_ * getRole() >> UpstreamsConfig.UpstreamRole.PRIMARY
_ * isAvailable() >> true
_ * getStatus() >> UpstreamAvailability.OK
}
]
when:
def act = new FilteredApis(Chain.ETHEREUM,
[] + lagging + ok,
Selector.empty, 0, 2, 0)
act.request(4)
then:
StepVerifier.create(act)
.expectNext(ok[0]).as("Initial requests with ok")
.expectNext(lagging[0]).as("Initial requests with lagging")
.expectNext(ok[0]).as("retry requests with ok")
.expectNext(lagging[0]).as("retry requests with lagging")
.expectComplete()
.verify(Duration.ofSeconds(1))
}
}