Skip to content

Commit 17d4c0b

Browse files
committed
fix: reuse connections to fix all known connection bugs
1 parent ce568d1 commit 17d4c0b

File tree

5 files changed

+39
-38
lines changed

5 files changed

+39
-38
lines changed

controller-runtime/build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ plugins {
55

66
dependencies {
77
api(project(":controller-shared"))
8-
api(rootProject.libs.kotlinCoroutines)
98
api(rootProject.libs.bundles.jooq)
109
api(rootProject.libs.sqliteJdbc)
1110
jooqCodegen(rootProject.libs.jooqMetaExtensions)

controller-runtime/src/main/kotlin/app/simplecloud/controller/runtime/host/ServerHostRepository.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import app.simplecloud.controller.runtime.Repository
44
import app.simplecloud.controller.runtime.server.ServerRepository
55
import app.simplecloud.controller.shared.host.ServerHost
66
import io.grpc.ConnectivityState
7+
import io.grpc.ManagedChannel
78
import kotlinx.coroutines.coroutineScope
89
import java.util.concurrent.ConcurrentHashMap
10+
import java.util.concurrent.TimeUnit
911

1012
class ServerHostRepository : Repository<ServerHost, ServerRepository> {
1113

@@ -26,15 +28,16 @@ class ServerHostRepository : Repository<ServerHost, ServerRepository> {
2628
suspend fun areServerHostsAvailable(): Boolean {
2729
return coroutineScope {
2830
return@coroutineScope hosts.any {
29-
val channel = it.value.createChannel()
31+
val channel = it.value.stub.channel as ManagedChannel
3032
val state = channel.getState(true)
31-
channel.shutdown()
3233
state == ConnectivityState.IDLE || state == ConnectivityState.READY
3334
}
3435
}
3536
}
3637

3738
override suspend fun delete(element: ServerHost): Boolean {
39+
val host = hosts.get(element.id) ?: return false
40+
(host.stub.channel as ManagedChannel).shutdown().awaitTermination(5L, TimeUnit.SECONDS)
3841
return hosts.remove(element.id, element)
3942
}
4043

controller-runtime/src/main/kotlin/app/simplecloud/controller/runtime/server/ServerService.kt

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class ServerService(
2929
private val logger = LogManager.getLogger(ServerService::class.java)
3030

3131
override suspend fun attachServerHost(request: AttachServerHostRequest): ServerHostDefinition {
32-
val serverHost = ServerHost.fromDefinition(request.serverHost)
32+
val serverHost = ServerHost.fromDefinition(request.serverHost, authCallCredentials)
3333
try {
3434
hostRepository.delete(serverHost)
3535
hostRepository.save(serverHost)
@@ -39,21 +39,17 @@ class ServerService(
3939
logger.info("Successfully registered ServerHost ${serverHost.id}.")
4040

4141
coroutineScope {
42-
val channel = serverHost.createChannel()
43-
val stub =
44-
ServerHostServiceGrpcKt.ServerHostServiceCoroutineStub(channel).withCallCredentials(authCallCredentials)
4542
serverRepository.findServersByHostId(serverHost.id).forEach { server ->
4643
logger.info("Reattaching Server ${server.uniqueId} of group ${server.group}...")
4744
try {
48-
val result = stub.reattachServer(server.toDefinition())
45+
val result = serverHost.stub.reattachServer(server.toDefinition())
4946
serverRepository.save(Server.fromDefinition(result))
5047
logger.info("Success!")
5148
} catch (e: Exception) {
5249
logger.error("Server was found to be offline, unregistering...")
5350
serverRepository.delete(server)
5451
}
5552
}
56-
channel.shutdown()
5753
}
5854
return serverHost.toDefinition()
5955
}
@@ -73,7 +69,7 @@ class ServerService(
7369
val server = serverRepository.findServerByNumerical(request.groupName, request.numericalId.toInt())
7470
?: throw StatusException(Status.NOT_FOUND.withDescription("No server was found matching this group and numerical id"))
7571
try {
76-
return stopServer(server.toDefinition())
72+
return stopServer(server.toDefinition(), request.stopCause)
7773
} catch (e: Exception) {
7874
throw StatusException(
7975
Status.INTERNAL.withDescription("Error occured whilest cleaning up stopped server: ").withCause(e)
@@ -167,9 +163,7 @@ class ServerService(
167163
val numericalId = numericalIdRepository.findNextNumericalId(group.name)
168164
val server = buildServer(group, numericalId, forwardingSecret)
169165
serverRepository.save(server)
170-
val channel = host.createChannel()
171-
val stub = ServerHostServiceGrpcKt.ServerHostServiceCoroutineStub(channel)
172-
.withCallCredentials(authCallCredentials)
166+
val stub = host.stub
173167
serverRepository.save(server)
174168
try {
175169
val result = stub.startServer(
@@ -179,12 +173,10 @@ class ServerService(
179173
.build()
180174
)
181175
serverRepository.save(Server.fromDefinition(result))
182-
channel.shutdown()
183176
return result
184177
} catch (e: Exception) {
185178
serverRepository.delete(server)
186179
numericalIdRepository.removeNumericalId(group.name, server.numericalId)
187-
channel.shutdown()
188180
logger.error("Error whilst starting server:", e)
189181
throw e
190182
}
@@ -206,7 +198,7 @@ class ServerService(
206198
.setUniqueId(UUID.randomUUID().toString().replace("-", "")).putAllCloudProperties(
207199
mapOf(
208200
*group.properties.entries.map { it.key to it.value }.toTypedArray(),
209-
"forwarding-secret" to forwardingSecret,
201+
"forwarding-secret" to forwardingSecret
210202
)
211203
).build()
212204
)
@@ -216,32 +208,30 @@ class ServerService(
216208
val server = serverRepository.find(request.serverId)
217209
?: throw StatusException(Status.NOT_FOUND.withDescription("No server was found matching this id."))
218210
try {
219-
val stopped = stopServer(server.toDefinition())
220-
pubSubClient.publish(
221-
"event", ServerStopEvent.newBuilder()
222-
.setServer(stopped)
223-
.setStoppedAt(ProtoBufTimestamp.fromLocalDateTime(LocalDateTime.now()))
224-
.setStopCause(request.stopCause)
225-
.setTerminationMode(ServerTerminationMode.UNKNOWN_MODE) //TODO: Add proto fields to make changing this possible
226-
.build()
227-
)
211+
val stopped = stopServer(server.toDefinition(), request.stopCause)
228212
return stopped
229213
} catch (e: Exception) {
230214
throw StatusException(Status.INTERNAL.withDescription("Error whilst stopping server").withCause(e))
231215
}
232216
}
233217

234-
private suspend fun stopServer(server: ServerDefinition): ServerDefinition {
218+
private suspend fun stopServer(server: ServerDefinition, cause: ServerStopCause = ServerStopCause.NATURAL_STOP): ServerDefinition {
235219
val host = hostRepository.findServerHostById(server.hostId)
236220
?: throw Status.NOT_FOUND
237221
.withDescription("No server host was found matching this server.")
238222
.asRuntimeException()
239-
val channel = host.createChannel()
240-
val stub = ServerHostServiceGrpcKt.ServerHostServiceCoroutineStub(channel)
241-
.withCallCredentials(authCallCredentials)
223+
val stub = host.stub
242224
try {
243225
val stopped = stub.stopServer(server)
244-
channel.shutdown()
226+
pubSubClient.publish(
227+
"event", ServerStopEvent.newBuilder()
228+
.setServer(stopped)
229+
.setStoppedAt(ProtoBufTimestamp.fromLocalDateTime(LocalDateTime.now()))
230+
.setStopCause(cause)
231+
.setTerminationMode(ServerTerminationMode.UNKNOWN_MODE) //TODO: Add proto fields to make changing this possible
232+
.build()
233+
)
234+
serverRepository.delete(Server.fromDefinition(stopped))
245235
return stopped
246236
} catch (e: Exception) {
247237
logger.error("Server stop error occured:", e)

controller-shared/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ dependencies {
33
api(rootProject.libs.simpleCloudPubSub)
44
api(rootProject.libs.bundles.configurate)
55
api(rootProject.libs.clikt)
6+
api(rootProject.libs.kotlinCoroutines)
67
}
Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package app.simplecloud.controller.shared.host
22

3+
import app.simplecloud.controller.shared.auth.AuthCallCredentials
34
import build.buf.gen.simplecloud.controller.v1.ServerHostDefinition
5+
import build.buf.gen.simplecloud.controller.v1.ServerHostServiceGrpcKt
46
import io.grpc.ManagedChannel
57
import io.grpc.ManagedChannelBuilder
68
import org.spongepowered.configurate.objectmapping.ConfigSerializable
@@ -9,7 +11,8 @@ import org.spongepowered.configurate.objectmapping.ConfigSerializable
911
data class ServerHost(
1012
val id: String,
1113
val host: String,
12-
val port: Int
14+
val port: Int,
15+
val stub: ServerHostServiceGrpcKt.ServerHostServiceCoroutineStub,
1316
) {
1417

1518
fun toDefinition(): ServerHostDefinition {
@@ -22,18 +25,23 @@ data class ServerHost(
2225

2326
companion object {
2427
@JvmStatic
25-
fun fromDefinition(serverHostDefinition: ServerHostDefinition): ServerHost {
28+
fun fromDefinition(serverHostDefinition: ServerHostDefinition, credentials: AuthCallCredentials): ServerHost {
2629
return ServerHost(
2730
serverHostDefinition.hostId,
2831
serverHostDefinition.hostHost,
29-
serverHostDefinition.hostPort
32+
serverHostDefinition.hostPort,
33+
ServerHostServiceGrpcKt.ServerHostServiceCoroutineStub(
34+
createChannel(
35+
serverHostDefinition.hostHost,
36+
serverHostDefinition.hostPort
37+
)
38+
).withCallCredentials(credentials),
3039
)
3140
}
32-
}
33-
3441

35-
fun createChannel(): ManagedChannel {
36-
return ManagedChannelBuilder.forAddress(host, port).usePlaintext().build()
42+
@JvmStatic
43+
fun createChannel(host: String, port: Int): ManagedChannel {
44+
return ManagedChannelBuilder.forAddress(host, port).usePlaintext().build()
45+
}
3746
}
38-
3947
}

0 commit comments

Comments
 (0)