Fixes head liveness check: timeout logic and periodic false negative events (#280)
This commit is contained in:
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user