feat(core, network): Port-Guards für Mehrfachstarts von P2P-Server integriert
Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
This commit is contained in:
+32
-1
@@ -15,9 +15,15 @@ import kotlinx.coroutines.flow.*
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
class JvmP2pSyncService : P2pSyncService {
|
class JvmP2pSyncService : P2pSyncService {
|
||||||
|
companion object {
|
||||||
|
// Prozessweiter, portbasierter Guard gegen Mehrfachstart
|
||||||
|
private val startedPorts: MutableSet<Int> = ConcurrentHashMap.newKeySet()
|
||||||
|
}
|
||||||
private var server: EmbeddedServer<*, *>? = null
|
private var server: EmbeddedServer<*, *>? = null
|
||||||
|
private var currentPort: Int? = null
|
||||||
private val client = HttpClient {
|
private val client = HttpClient {
|
||||||
install(io.ktor.client.plugins.websocket.WebSockets)
|
install(io.ktor.client.plugins.websocket.WebSockets)
|
||||||
}
|
}
|
||||||
@@ -32,8 +38,19 @@ class JvmP2pSyncService : P2pSyncService {
|
|||||||
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||||
|
|
||||||
override fun startServer(port: Int) {
|
override fun startServer(port: Int) {
|
||||||
if (server != null) return
|
// Instanz-Guard (gleiche Instanz)
|
||||||
|
if (server != null) {
|
||||||
|
println("[P2P Server] Bereits gestartet (Instanz) auf Port ${currentPort ?: port} – idempotent")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prozessweiter, portbasierter Guard
|
||||||
|
if (!startedPorts.add(port)) {
|
||||||
|
println("[P2P Server] Bereits gestartet (Prozess) auf Port $port – idempotent, kein neuer Bind")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
server = embeddedServer(Netty, port = port) {
|
server = embeddedServer(Netty, port = port) {
|
||||||
install(io.ktor.server.websocket.WebSockets)
|
install(io.ktor.server.websocket.WebSockets)
|
||||||
routing {
|
routing {
|
||||||
@@ -61,12 +78,26 @@ class JvmP2pSyncService : P2pSyncService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.start(wait = false)
|
}.start(wait = false)
|
||||||
|
currentPort = port
|
||||||
println("[P2P Server] Gestartet auf Port $port")
|
println("[P2P Server] Gestartet auf Port $port")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
// Start fehlgeschlagen -> Port-Lock wieder freigeben
|
||||||
|
startedPorts.remove(port)
|
||||||
|
server = null
|
||||||
|
currentPort = null
|
||||||
|
println("[P2P Server] Start auf Port $port fehlgeschlagen: ${e.message}")
|
||||||
|
throw e
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun stopServer() {
|
override fun stopServer() {
|
||||||
|
try {
|
||||||
server?.stop(1000, 2000)
|
server?.stop(1000, 2000)
|
||||||
|
} finally {
|
||||||
server = null
|
server = null
|
||||||
|
currentPort?.let { startedPorts.remove(it) }
|
||||||
|
currentPort = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun connectToPeer(host: String, port: Int) {
|
override suspend fun connectToPeer(host: String, port: Int) {
|
||||||
|
|||||||
Reference in New Issue
Block a user