problem: gives no status updates if chain is not configured

This commit is contained in:
Igor Artamonov
2021-07-31 22:06:02 -04:00
parent e73920b4c9
commit 96109d4013
4 changed files with 92 additions and 19 deletions

View File

@@ -35,7 +35,7 @@ class Describe(
val resp = BlockchainOuterClass.DescribeResponse.newBuilder()
multistreamHolder.getAvailable().forEach { chain ->
multistreamHolder.getUpstream(chain)?.let { chainUpstreams ->
val status = subscribeStatus.chainStatus(chain, chainUpstreams.getAll())
val status = subscribeStatus.chainStatus(chain, chainUpstreams.getStatus(), chainUpstreams)
val targets = chainUpstreams.getMethods().getSupportedMethods()
val capabilities: MutableSet<Capability> = mutableSetOf()
val chainDescription = BlockchainOuterClass.DescribeChain.newBuilder()

View File

@@ -31,28 +31,41 @@ class SubscribeStatus(
) {
fun subscribeStatus(requestMono: Mono<BlockchainOuterClass.StatusRequest>): Flux<BlockchainOuterClass.ChainStatus> {
return requestMono.flatMapMany {
val ups = multistreamHolder.getAvailable().mapNotNull { chain ->
val chainUpstream = multistreamHolder.getUpstream(chain)
chainUpstream?.observeStatus()?.map { avail ->
ChainSubscription(chain, chainUpstream, avail)
return requestMono.flatMapMany { req ->
// check status for all requested chains
val all = req.chainsList.map {
val chain = Chain.byId(it.number)
val up = multistreamHolder.getUpstream(chain)
if (up == null) {
// when the chain is not configured return just UNAVAILABLE
Mono.just(chainUnavailable(chain)).flux()
} else {
// when configured subscribe to its updates
up.observeStatus().map { availability ->
chainStatus(chain, availability, up)
}
}
}
Flux.merge(ups)
.map {
chainStatus(it.chain, it.up.getAll())
}
Flux.merge(all)
}
}
fun chainStatus(chain: Chain, ups: List<Upstream>): BlockchainOuterClass.ChainStatus {
val available = ups.map { u ->
u.getStatus()
}.min() ?: UpstreamAvailability.UNAVAILABLE
val quorum = ups.filter {
it.getStatus() > UpstreamAvailability.UNAVAILABLE
}.count()
fun chainUnavailable(chain: Chain): BlockchainOuterClass.ChainStatus {
return BlockchainOuterClass.ChainStatus.newBuilder()
.setAvailability(BlockchainOuterClass.AvailabilityEnum.AVAIL_UNAVAILABLE)
.setChain(Common.ChainRef.forNumber(chain.id))
.setQuorum(0)
.build()
}
fun chainStatus(chain: Chain, available: UpstreamAvailability, ups: Multistream): BlockchainOuterClass.ChainStatus {
val quorum = if (available != UpstreamAvailability.UNAVAILABLE) {
ups.getAll().count {
it.getStatus() > UpstreamAvailability.UNAVAILABLE
}
} else {
0
}
return BlockchainOuterClass.ChainStatus.newBuilder()
.setAvailability(BlockchainOuterClass.AvailabilityEnum.forNumber(available.grpcId))
.setChain(Common.ChainRef.forNumber(chain.id))

View File

@@ -98,7 +98,7 @@ abstract class Multistream(
/**
* Get list of all underlying upstreams
*/
fun getAll(): List<Upstream> {
open fun getAll(): List<Upstream> {
return upstreams
}