Update labels (#302)

This commit is contained in:
KirillPamPam
2023-09-19 13:11:31 +04:00
committed by GitHub
parent 5a2e5e9304
commit 674bc18f25
5 changed files with 39 additions and 34 deletions

View File

@@ -19,9 +19,7 @@ package io.emeraldpay.dshackle.rpc
import io.emeraldpay.api.proto.BlockchainOuterClass
import io.emeraldpay.api.proto.Common
import io.emeraldpay.dshackle.Global
import io.emeraldpay.dshackle.startup.QuorumForLabels
import io.emeraldpay.dshackle.upstream.Capability
import io.emeraldpay.dshackle.upstream.DefaultUpstream
import io.emeraldpay.dshackle.upstream.MultistreamHolder
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
@@ -48,28 +46,21 @@ class Describe(
.addAllSupportedSubscriptions(chainUpstreams.getEgressSubscription().getAvailableTopics())
.setStatus(status)
.setCurrentHeight(chainUpstreams.getHead().getCurrentHeight() ?: 0)
chainUpstreams.getAll().let { ups ->
ups.forEach { up ->
val nodes = QuorumForLabels()
if (up is DefaultUpstream) {
nodes.add(up.getQuorumByLabel())
}
nodes.getAll().forEach { node ->
val nodeDetails = BlockchainOuterClass.NodeDetails.newBuilder()
.setQuorum(node.quorum)
.addAllLabels(
node.labels.entries.map { label ->
BlockchainOuterClass.Label.newBuilder()
.setName(label.key)
.setValue(label.value)
.build()
}
)
chainDescription.addNodes(nodeDetails)
}
capabilities.addAll(up.getCapabilities())
chainUpstreams.getQuorumLabels()
.forEach { node ->
val nodeDetails = BlockchainOuterClass.NodeDetails.newBuilder()
.setQuorum(node.quorum)
.addAllLabels(
node.labels.entries.map { label ->
BlockchainOuterClass.Label.newBuilder()
.setName(label.key)
.setValue(label.value)
.build()
}
)
chainDescription.addNodes(nodeDetails)
}
}
capabilities.addAll(chainUpstreams.getCapabilities())
chainDescription.addAllCapabilities(
capabilities.map {
when (it) {

View File

@@ -21,6 +21,7 @@ import io.emeraldpay.dshackle.cache.Caches
import io.emeraldpay.dshackle.cache.CachesEnabled
import io.emeraldpay.dshackle.config.UpstreamsConfig
import io.emeraldpay.dshackle.reader.JsonRpcReader
import io.emeraldpay.dshackle.startup.QuorumForLabels
import io.emeraldpay.dshackle.startup.UpstreamChangeEvent
import io.emeraldpay.dshackle.upstream.calls.AggregatedCallMethods
import io.emeraldpay.dshackle.upstream.calls.CallMethods
@@ -63,6 +64,7 @@ abstract class Multistream(
private var cacheSubscription: Disposable? = null
private val reconfigLock = ReentrantLock()
private val eventLock = ReentrantLock()
@Volatile
private var callMethods: CallMethods? = null
private var callMethodsFactory: Factory<CallMethods> = Factory {
return@Factory callMethods ?: throw FunctorException("Not initialized yet")
@@ -70,7 +72,10 @@ abstract class Multistream(
private var seq = 0
protected var lagObserver: HeadLagObserver? = null
private var subscription: Disposable? = null
@Volatile
private var capabilities: Set<Capability> = emptySet()
@Volatile
private var quorumLabels: List<QuorumForLabels.QuorumItem>? = null
private val removed: MutableMap<String, Upstream> = HashMap()
private val meters: MutableMap<String, List<Meter.Id>> = HashMap()
private val addedUpstreams = Sinks.many()
@@ -203,13 +208,14 @@ abstract class Multistream(
open fun onUpstreamsUpdated() {
reconfigLock.withLock {
val upstreams = getAll()
upstreams.filter { it.isAvailable() }.map { it.getMethods() }.let {
val availableUpstreams = upstreams.filter { it.isAvailable() }
availableUpstreams.map { it.getMethods() }.let {
callMethods = AggregatedCallMethods(it)
}
capabilities = if (upstreams.isEmpty()) {
emptySet()
} else {
upstreams.filter { it.isAvailable() }.map { up ->
availableUpstreams.map { up ->
up.getCapabilities()
}.let {
if (it.isNotEmpty()) {
@@ -219,6 +225,7 @@ abstract class Multistream(
}
}
}
quorumLabels = getQuorumLabels(availableUpstreams)
when {
upstreams.size == 1 -> {
lagObserver?.stop()
@@ -230,6 +237,18 @@ abstract class Multistream(
}
}
private fun getQuorumLabels(ups: List<Upstream>): List<QuorumForLabels.QuorumItem> {
val nodes = QuorumForLabels()
ups.forEach { up ->
if (up is DefaultUpstream) {
nodes.add(up.getQuorumByLabel())
}
}
return nodes.getAll()
}
fun getQuorumLabels(): List<QuorumForLabels.QuorumItem> = quorumLabels ?: emptyList()
override fun observeStatus(): Flux<UpstreamAvailability> {
val upstreamsFluxes = getAll().map { up ->
Flux.concat(
@@ -457,9 +476,4 @@ abstract class Multistream(
return map.values.min()
}
}
data class UpstreamChangeState(
val upId: String,
val status: UpstreamAvailability
)
}

View File

@@ -54,10 +54,11 @@ class GrpcUpstreamStatus(
}
this.nodes.set(updateNodes)
val labelsChanged = updateLabels != this.allLabels.get().toList()
this.allLabels.set(Collections.unmodifiableCollection(updateLabels))
val changed = conf.supportedMethodsList.toSet() != this.targets?.getSupportedMethods()
this.targets = DirectCallMethods(conf.supportedMethodsList.toSet())
return changed
return changed || labelsChanged
}
fun getLabels(): Collection<UpstreamsConfig.Labels> {

View File

@@ -81,7 +81,7 @@ class GrpcUpstreamStatusSpec extends Specification {
)
act = status.getLabels()
then:
!result
result
act.toList() == [
UpstreamsConfig.Labels.fromMap([test1: "bar", test2: "baz"])
]
@@ -125,7 +125,7 @@ class GrpcUpstreamStatusSpec extends Specification {
)
act = status.getLabels()
then:
!result
result
act.toList() == [
UpstreamsConfig.Labels.fromMap([test: "bar", fix: "value"])
]

View File

@@ -72,7 +72,6 @@ class IntegrationTest {
val result = stub.describe(BlockchainOuterClass.DescribeRequest.newBuilder().build())
Assertions.assertThat(result.chainsCount).isEqualTo(1)
Assertions.assertThat(result.chainsList[0].chain).isEqualTo(ChainRef.CHAIN_ETHEREUM__MAINNET)
Assertions.assertThat(result.chainsList[0].nodesCount).isEqualTo(1)
}
@TestConfiguration