@@ -11,21 +11,26 @@ import reactor.core.publisher.Flux
1111import reactor.core.publisher.Sinks
1212import java.io.Closeable
1313import java.net.URI
14+ import java.util.concurrent.ConcurrentHashMap
15+ import java.util.concurrent.CopyOnWriteArrayList
1416import java.util.concurrent.Executors
1517import java.util.concurrent.TimeUnit
1618
1719/* *
1820 * @param userId ID of the bot for authenticating with Discord
1921 */
2022class LavalinkClient (val userId : Long ) : Closeable, Disposable {
21- private val internalNodes = mutableListOf <LavalinkNode >()
22- private val links = mutableMapOf <Long , Link >()
23+ private val internalNodes = CopyOnWriteArrayList <LavalinkNode >()
24+ private val linkMap = ConcurrentHashMap <Long , Link >()
2325 private var clientOpen = true
2426
2527 // Immutable public list
2628 val nodes: List <LavalinkNode >
2729 get() = internalNodes.toList()
2830
31+ val links: List <Link >
32+ get() = linkMap.values.toList()
33+
2934 // Events forwarded from all nodes.
3035 private val sink: Sinks .Many <ClientEvent <* >> = Sinks .many().multicast().onBackpressureBuffer()
3136 val flux: Flux <ClientEvent <* >> = sink.asFlux()
@@ -70,6 +75,9 @@ class LavalinkClient(val userId: Long) : Closeable, Disposable {
7075 return node
7176 }
7277
78+ /* *
79+ * Remove a node by its [name].
80+ */
7381 fun removeNode (name : String ): Boolean {
7482 val node = nodes.firstOrNull { it.name == name }
7583
@@ -80,6 +88,9 @@ class LavalinkClient(val userId: Long) : Closeable, Disposable {
8088 return removeNode(node)
8189 }
8290
91+ /* *
92+ * Disconnect and remove a node the client.
93+ */
8394 fun removeNode (node : LavalinkNode ): Boolean {
8495 if (node !in internalNodes) {
8596 return false
@@ -100,19 +111,19 @@ class LavalinkClient(val userId: Long) : Closeable, Disposable {
100111 */
101112 @JvmOverloads
102113 fun getLink (guildId : Long , region : VoiceRegion ? = null): Link {
103- if (guildId !in links ) {
114+ if (! linkMap.containsKey(guildId) ) {
104115 val bestNode = loadBalancer.selectNode(region)
105- links [guildId] = Link (guildId, bestNode)
116+ linkMap [guildId] = Link (guildId, bestNode)
106117 }
107118
108- return links [guildId]!!
119+ return linkMap [guildId]!!
109120 }
110121
111122 /* *
112123 * Returns a [Link] if it exists in the cache.
113124 * If we select a link for voice updates, we don't know the region yet.
114125 */
115- fun getLinkIfCached (guildId : Long ): Link ? = links [guildId]
126+ fun getLinkIfCached (guildId : Long ): Link ? = linkMap [guildId]
116127
117128 internal fun onNodeDisconnected (node : LavalinkNode ) {
118129 // Don't do anything if we are shutting down.
@@ -121,13 +132,13 @@ class LavalinkClient(val userId: Long) : Closeable, Disposable {
121132 }
122133
123134 if (nodes.size == 1 ) {
124- links .forEach { (_, link) ->
135+ linkMap .forEach { (_, link) ->
125136 link.state = LinkState .DISCONNECTED
126137 }
127138 return
128139 }
129140
130- links .forEach { (_, link) ->
141+ linkMap .forEach { (_, link) ->
131142 if (link.node == node) {
132143 link.transferNode(loadBalancer.selectNode(region = null ))
133144 }
0 commit comments