Fixes head liveness check: timeout logic and periodic false negative events (#280)

This commit is contained in:
Vyacheslav
2023-08-14 21:36:37 +03:00
committed by GitHub
parent 6ff75f0e7c
commit e0cce9aeab
5 changed files with 47 additions and 12 deletions

View File

@@ -26,7 +26,7 @@ import reactor.core.publisher.Sinks
class EthereumHeadMock implements Head {
private Sinks.Many<BlockContainer> bus = Sinks.many().multicast().onBackpressureBuffer()
private Sinks.Many<BlockContainer> bus = Sinks.many().multicast().onBackpressureBuffer(10, false)
private Publisher<BlockContainer> predefined = null
private BlockContainer latest
private List<Runnable> handlers = []
@@ -54,7 +54,7 @@ class EthereumHeadMock implements Head {
if (predefined != null) {
return Flux.concat(Mono.justOrEmpty(latest), Flux.from(predefined))
} else {
return Flux.concat(Mono.justOrEmpty(latest), bus.asFlux()).distinctUntilChanged()
return Flux.concat(Mono.justOrEmpty(latest), bus.asFlux())
}
}

View File

@@ -7,12 +7,14 @@ import reactor.test.StepVerifier
import spock.lang.Specification
import java.time.Duration
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
class HeadLivenessValidatorSpec extends Specification{
def "emits true"() {
when:
def head = new EthereumHeadMock()
def checker = new HeadLivenessValidator(head, Duration.ofSeconds(10), Schedulers.boundedElastic())
def checker = new HeadLivenessValidator(head, Duration.ofSeconds(10), Schedulers.boundedElastic(), "test")
then:
StepVerifier.create(checker.flux)
.then {
@@ -25,7 +27,7 @@ class HeadLivenessValidatorSpec extends Specification{
def "starts accumulating trues but immediately emits after false"() {
when:
def head = new EthereumHeadMock()
def checker = new HeadLivenessValidator(head, Duration.ofSeconds(100), Schedulers.boundedElastic())
def checker = new HeadLivenessValidator(head, Duration.ofSeconds(100), Schedulers.boundedElastic(), "test")
then:
StepVerifier.create(checker.flux)
.then {
@@ -43,7 +45,7 @@ class HeadLivenessValidatorSpec extends Specification{
def "starts accumulating trues but timeouts because head staled"() {
when:
def head = new EthereumHeadMock()
def checker = new HeadLivenessValidator(head, Duration.ofMillis(100), Schedulers.boundedElastic())
def checker = new HeadLivenessValidator(head, Duration.ofMillis(100), Schedulers.boundedElastic(), "test")
then:
StepVerifier.create(checker.flux)
.then {
@@ -54,4 +56,25 @@ class HeadLivenessValidatorSpec extends Specification{
.expectNext(false)
.thenCancel().verify(Duration.ofSeconds(2))
}
def "it recovers after timeout"() {
when:
def head = new EthereumHeadMock()
def checker = new HeadLivenessValidator(head, Duration.ofMillis(200), Schedulers.boundedElastic(), "test")
then:
StepVerifier.create(checker.flux)
.then {
head.nextBlock(TestingCommons.blockForEthereum(1))
head.nextBlock(TestingCommons.blockForEthereum(2))
}
.thenAwait(Duration.ofSeconds(1))
.expectNext(false)
.then {
head.nextBlock(TestingCommons.blockForEthereum(3))
head.nextBlock(TestingCommons.blockForEthereum(4))
head.nextBlock(TestingCommons.blockForEthereum(5))
}
.expectNext(true)
.thenCancel().verify(Duration.ofSeconds(3))
}
}