lm-sistemi-software-distrib.../src/main/kotlin/drills/drill09/gossip/QueryNode.kt

77 lines
2.1 KiB
Kotlin

package drills.drill09.gossip
import util.network.epidemic.EpidemicNode
import util.network.epidemic.packet.EpidemicPacket
import util.network.epidemic.packet.FeedbackEpidemicPacket
import util.network.simulator.Address
import util.network.simulator.Network
import kotlin.random.Random
class QueryNode<T>(
address: Address,
network: Network,
initialValue: T,
private val demotivatingFactor: Int = 10,
bufferSize: Int = 1
) : EpidemicNode<T, FeedbackEpidemicPacket<T>>(
address, network, initialValue, bufferSize
) {
private var queryValue: T = nodeValue
private var random = Random(System.currentTimeMillis())
override fun makeInfectionPacket(
receiverAddress: Address,
type: EpidemicPacket.Type
): EpidemicPacket<T> {
return FeedbackEpidemicPacket(
address,
receiverAddress,
queryValue,
type,
false
)
}
override fun receivePushOrReply(packet: FeedbackEpidemicPacket<T>) {
when (nodeState) {
State.REMOVED -> return
State.INFECTED -> whenInfected(packet)
State.SUSCEPTIBLE -> whenSusceptible(packet)
}
}
private fun whenSusceptible(packet: FeedbackEpidemicPacket<T>) {
nodeState = State.INFECTED
queryValue = packet.payload
sendPushToRandom(2)
if (packet.payload == nodeValue)
println("find ${packet.payload} on node $address")
}
private fun whenInfected(packet: FeedbackEpidemicPacket<T>) {
if (!packet.isFeedback)
send(
FeedbackEpidemicPacket(
address,
packet.senderAddress,
queryValue,
EpidemicPacket.Type.PUSH,
true
)
)
if (packet.isFeedback && random.nextDouble(1.0) < 1 / demotivatingFactor)
nodeState = State.REMOVED
}
override fun receivePull(packet: FeedbackEpidemicPacket<T>) {
TODO("Not yet implemented")
}
override fun infect() {
Thread.interrupted()
}
}