Skip to content

Commit 396aaa2

Browse files
committed
Refactor SimpleDataSource into an interface, add AutoCloseable support, and encapsulate implementation details in a factory method.
1 parent cd7c6f1 commit 396aaa2

1 file changed

Lines changed: 45 additions & 25 deletions

File tree

util/src/main/kotlin/com/caplin/integration/datasourcex/util/SimpleDataSource.kt

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,45 +5,65 @@ import com.caplin.datasource.Peer
55
import com.caplin.datasource.PeerStatus
66
import com.caplin.datasource.PeerStatus.DOWN
77
import com.caplin.datasource.PeerStatus.UP
8+
import java.lang.AutoCloseable
89
import java.util.concurrent.locks.ReentrantLock
910
import kotlin.concurrent.withLock
1011
import kotlinx.collections.immutable.toPersistentMap
1112
import kotlinx.coroutines.flow.MutableSharedFlow
13+
import kotlinx.coroutines.flow.SharedFlow
1214
import kotlinx.coroutines.flow.asSharedFlow
1315
import kotlinx.coroutines.flow.first
1416

15-
class SimpleDataSource(private val dataSource: DataSource) : DataSource by dataSource {
17+
interface SimpleDataSource : DataSource, AutoCloseable {
1618

17-
private val _state =
18-
MutableSharedFlow<Map<Peer, PeerStatus>>(replay = 1, extraBufferCapacity = Int.MAX_VALUE)
19+
companion object {
20+
operator fun invoke(dataSource: DataSource): SimpleDataSource =
21+
object : SimpleDataSource, DataSource by dataSource {
1922

20-
init {
21-
var knownPeers = dataSource.peers.associate { PeerKey(it) as Peer to DOWN }.toPersistentMap()
22-
_state.tryEmit(knownPeers)
23-
val lock = ReentrantLock()
24-
dataSource.addConnectionListener {
25-
lock.withLock {
26-
knownPeers = knownPeers.putting(PeerKey(it.peer), it.peerStatus)
27-
_state.tryEmit(knownPeers)
28-
}
29-
}
30-
}
23+
private val _state =
24+
MutableSharedFlow<Map<Peer, PeerStatus>>(
25+
replay = 1,
26+
extraBufferCapacity = Int.MAX_VALUE,
27+
)
3128

32-
val peerStates = _state.asSharedFlow()
29+
init {
30+
var knownPeers =
31+
dataSource.peers.associate { PeerKey(it) as Peer to DOWN }.toPersistentMap()
32+
_state.tryEmit(knownPeers)
33+
val lock = ReentrantLock()
34+
dataSource.addConnectionListener {
35+
lock.withLock {
36+
knownPeers = knownPeers.putting(PeerKey(it.peer), it.peerStatus)
37+
_state.tryEmit(knownPeers)
38+
}
39+
}
40+
}
3341

34-
/** Await all known peers to be connected */
35-
suspend fun awaitConnected() {
36-
_state.first { it.values.all { it == UP } }
37-
}
42+
override val peerStates = _state.asSharedFlow()
43+
44+
/** Await all known peers to be connected */
45+
override suspend fun awaitConnected() {
46+
_state.first { it.values.all { it == UP } }
47+
}
3848

39-
/** A [Peer] whose identity is its index, so it can be used as a map key. */
40-
private class PeerKey(peer: Peer) : Peer by peer {
41-
override fun equals(other: Any?) = other is PeerKey && other.index == index
49+
override fun close() {
50+
dataSource.stop()
51+
}
52+
}
4253

43-
override fun hashCode() = index
54+
/** A [Peer] whose identity is its index, so it can be used as a map key. */
55+
private class PeerKey(peer: Peer) : Peer by peer {
56+
override fun equals(other: Any?) = other is PeerKey && other.index == index
4457

45-
override fun getLoggingId(): String? {
46-
return super.getLoggingId()
58+
override fun hashCode() = index
59+
60+
override fun getLoggingId(): String? {
61+
return super.getLoggingId()
62+
}
4763
}
4864
}
65+
66+
val peerStates: SharedFlow<Map<Peer, PeerStatus>>
67+
68+
suspend fun awaitConnected()
4969
}

0 commit comments

Comments
 (0)