mirror of
https://github.com/ethauvin/kobalt.git
synced 2025-04-26 08:27:12 -07:00
Make KobaltServer more resilient.
This commit is contained in:
parent
8c13df5be1
commit
1624db10d7
1 changed files with 50 additions and 19 deletions
|
@ -3,6 +3,7 @@ package com.beust.kobalt.app.remote
|
||||||
import com.beust.kobalt.Args
|
import com.beust.kobalt.Args
|
||||||
import com.beust.kobalt.api.Kobalt
|
import com.beust.kobalt.api.Kobalt
|
||||||
import com.beust.kobalt.homeDir
|
import com.beust.kobalt.homeDir
|
||||||
|
import com.beust.kobalt.internal.PluginInfo
|
||||||
import com.beust.kobalt.internal.remote.CommandData
|
import com.beust.kobalt.internal.remote.CommandData
|
||||||
import com.beust.kobalt.internal.remote.ICommandSender
|
import com.beust.kobalt.internal.remote.ICommandSender
|
||||||
import com.beust.kobalt.internal.remote.PingCommand
|
import com.beust.kobalt.internal.remote.PingCommand
|
||||||
|
@ -19,8 +20,8 @@ import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class KobaltServer @Inject constructor(val args: Args) : Runnable, ICommandSender {
|
public class KobaltServer @Inject constructor(val args: Args, val pluginInfo: PluginInfo) : Runnable, ICommandSender {
|
||||||
var outgoing: PrintWriter? = null
|
// var outgoing: PrintWriter? = null
|
||||||
val pending = arrayListOf<CommandData>()
|
val pending = arrayListOf<CommandData>()
|
||||||
|
|
||||||
private val COMMAND_CLASSES = listOf(GetDependenciesCommand::class.java, PingCommand::class.java)
|
private val COMMAND_CLASSES = listOf(GetDependenciesCommand::class.java, PingCommand::class.java)
|
||||||
|
@ -30,8 +31,11 @@ public class KobaltServer @Inject constructor(val args: Args) : Runnable, IComma
|
||||||
|
|
||||||
override fun run() {
|
override fun run() {
|
||||||
try {
|
try {
|
||||||
createServerFile(args.port)
|
if (createServerFile(args.port)) {
|
||||||
privateRun()
|
privateRun()
|
||||||
|
}
|
||||||
|
} catch(ex: Exception) {
|
||||||
|
ex.printStackTrace()
|
||||||
} finally {
|
} finally {
|
||||||
deleteServerFile()
|
deleteServerFile()
|
||||||
}
|
}
|
||||||
|
@ -40,11 +44,17 @@ public class KobaltServer @Inject constructor(val args: Args) : Runnable, IComma
|
||||||
val SERVER_FILE = KFiles.joinDir(homeDir(KFiles.KOBALT_DOT_DIR, "kobaltServer.properties"))
|
val SERVER_FILE = KFiles.joinDir(homeDir(KFiles.KOBALT_DOT_DIR, "kobaltServer.properties"))
|
||||||
val KEY_PORT = "port"
|
val KEY_PORT = "port"
|
||||||
|
|
||||||
private fun createServerFile(port: Int) {
|
private fun createServerFile(port: Int) : Boolean {
|
||||||
Properties().apply {
|
if (File(SERVER_FILE).exists()) {
|
||||||
put(KEY_PORT, port.toString())
|
log(1, "Server file $SERVER_FILE already exists, is another server running?")
|
||||||
}.store(FileWriter(SERVER_FILE), "")
|
return false
|
||||||
log(2, "KobaltServer created $SERVER_FILE")
|
} else {
|
||||||
|
Properties().apply {
|
||||||
|
put(KEY_PORT, port.toString())
|
||||||
|
}.store(FileWriter(SERVER_FILE), "")
|
||||||
|
log(2, "KobaltServer created $SERVER_FILE")
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deleteServerFile() {
|
private fun deleteServerFile() {
|
||||||
|
@ -52,15 +62,35 @@ public class KobaltServer @Inject constructor(val args: Args) : Runnable, IComma
|
||||||
File(SERVER_FILE).delete()
|
File(SERVER_FILE).delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lateinit var serverInfo: ServerInfo
|
||||||
|
|
||||||
|
class ServerInfo(val port: Int) {
|
||||||
|
lateinit var reader: BufferedReader
|
||||||
|
lateinit var writer: PrintWriter
|
||||||
|
var serverSocket : ServerSocket? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reset() {
|
||||||
|
if (serverSocket != null) {
|
||||||
|
serverSocket!!.close()
|
||||||
|
}
|
||||||
|
serverSocket = ServerSocket(port)
|
||||||
|
var clientSocket = serverSocket!!.accept()
|
||||||
|
reader = BufferedReader(InputStreamReader(clientSocket.inputStream))
|
||||||
|
writer = PrintWriter(clientSocket.outputStream, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun privateRun() {
|
private fun privateRun() {
|
||||||
val portNumber = args.port
|
val portNumber = args.port
|
||||||
|
|
||||||
log(1, "Listening to port $portNumber")
|
log(1, "Listening to port $portNumber")
|
||||||
var quit = false
|
var quit = false
|
||||||
val serverSocket = ServerSocket(portNumber)
|
serverInfo = ServerInfo(portNumber)
|
||||||
var clientSocket = serverSocket.accept()
|
|
||||||
while (!quit) {
|
while (!quit) {
|
||||||
outgoing = PrintWriter(clientSocket.outputStream, true)
|
|
||||||
if (pending.size > 0) {
|
if (pending.size > 0) {
|
||||||
log(1, "Emptying the queue, size $pending.size()")
|
log(1, "Emptying the queue, size $pending.size()")
|
||||||
synchronized(pending) {
|
synchronized(pending) {
|
||||||
|
@ -68,10 +98,9 @@ public class KobaltServer @Inject constructor(val args: Args) : Runnable, IComma
|
||||||
pending.clear()
|
pending.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val ins = BufferedReader(InputStreamReader(clientSocket.inputStream))
|
|
||||||
var commandName: String? = null
|
var commandName: String? = null
|
||||||
try {
|
try {
|
||||||
var line = ins.readLine()
|
var line = serverInfo.reader.readLine()
|
||||||
while (!quit && line != null) {
|
while (!quit && line != null) {
|
||||||
log(1, "Received from client $line")
|
log(1, "Received from client $line")
|
||||||
val jo = JsonParser().parse(line) as JsonObject
|
val jo = JsonParser().parse(line) as JsonObject
|
||||||
|
@ -85,15 +114,15 @@ public class KobaltServer @Inject constructor(val args: Args) : Runnable, IComma
|
||||||
// Done, send a quit to the client
|
// Done, send a quit to the client
|
||||||
sendData(CommandData("quit", ""))
|
sendData(CommandData("quit", ""))
|
||||||
|
|
||||||
line = ins.readLine()
|
line = serverInfo.reader.readLine()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (line == null) {
|
if (line == null) {
|
||||||
quit = true
|
serverInfo.reset()
|
||||||
}
|
}
|
||||||
} catch(ex: SocketException) {
|
} catch(ex: SocketException) {
|
||||||
log(1, "Client disconnected, resetting")
|
log(1, "Client disconnected, resetting")
|
||||||
clientSocket = serverSocket.accept()
|
serverInfo.reset()
|
||||||
} catch(ex: Throwable) {
|
} catch(ex: Throwable) {
|
||||||
ex.printStackTrace()
|
ex.printStackTrace()
|
||||||
if (commandName != null) {
|
if (commandName != null) {
|
||||||
|
@ -101,6 +130,8 @@ public class KobaltServer @Inject constructor(val args: Args) : Runnable, IComma
|
||||||
}
|
}
|
||||||
log(1, "Command failed: ${ex.message}")
|
log(1, "Command failed: ${ex.message}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pluginInfo.shutdown()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,8 +146,8 @@ public class KobaltServer @Inject constructor(val args: Args) : Runnable, IComma
|
||||||
|
|
||||||
override fun sendData(commandData: CommandData) {
|
override fun sendData(commandData: CommandData) {
|
||||||
val content = Gson().toJson(commandData)
|
val content = Gson().toJson(commandData)
|
||||||
if (outgoing != null) {
|
if (serverInfo.writer != null) {
|
||||||
outgoing!!.println(content)
|
serverInfo.writer!!.println(content)
|
||||||
} else {
|
} else {
|
||||||
log(1, "Queuing $content")
|
log(1, "Queuing $content")
|
||||||
synchronized(pending) {
|
synchronized(pending) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue