@@ -5,45 +5,65 @@ import com.caplin.datasource.Peer
55import com.caplin.datasource.PeerStatus
66import com.caplin.datasource.PeerStatus.DOWN
77import com.caplin.datasource.PeerStatus.UP
8+ import java.lang.AutoCloseable
89import java.util.concurrent.locks.ReentrantLock
910import kotlin.concurrent.withLock
1011import kotlinx.collections.immutable.toPersistentMap
1112import kotlinx.coroutines.flow.MutableSharedFlow
13+ import kotlinx.coroutines.flow.SharedFlow
1214import kotlinx.coroutines.flow.asSharedFlow
1315import 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