Changes to task cancelation and fix

- fixed generate command error on multiple tasks for one world
- changed check of task completion from polling to interrupt (via callback function)
release/0.11-beta
Trivernis 5 years ago
parent 132294d683
commit 5d0f158427

@ -21,9 +21,7 @@ class CmdCancel(private val chunkmaster: Chunkmaster): Subcommand {
args: List<String> args: List<String>
): MutableList<String> { ): MutableList<String> {
val genManager = chunkmaster.generationManager val genManager = chunkmaster.generationManager
val allTasks = HashSet<TaskEntry>() val allTasks = genManager.allTasks
allTasks.addAll(genManager.pausedTasks)
allTasks.addAll(genManager.tasks)
return allTasks.filter {it.id.toString().indexOf(args[0]) == 0} return allTasks.filter {it.id.toString().indexOf(args[0]) == 0}
.map { it.id.toString() }.toMutableList() .map { it.id.toString() }.toMutableList()
} }

@ -59,17 +59,21 @@ class CmdGenerate(private val chunkmaster: Chunkmaster): Subcommand {
} }
} }
val world = chunkmaster.server.getWorld(worldName) val world = chunkmaster.server.getWorld(worldName)
return if (world != null) { val allTasks = chunkmaster.generationManager.allTasks
return if (world != null && (allTasks.find { it.generationTask.world == world }) == null) {
chunkmaster.generationManager.addTask(world, stopAfter) chunkmaster.generationManager.addTask(world, stopAfter)
sender.spigot().sendMessage(*ComponentBuilder("Generation task for world ").color(ChatColor.BLUE) sender.spigot().sendMessage(*ComponentBuilder("Generation task for world ").color(ChatColor.BLUE)
.append(worldName).color(ChatColor.GREEN).append(" until ").color(ChatColor.BLUE) .append(worldName).color(ChatColor.GREEN).append(" until ").color(ChatColor.BLUE)
.append(if (stopAfter > 0) "$stopAfter chunks" else "WorldBorder").color(ChatColor.GREEN) .append(if (stopAfter > 0) "$stopAfter chunks" else "WorldBorder").color(ChatColor.GREEN)
.append(" successfully created").color(ChatColor.BLUE).create()) .append(" successfully created").color(ChatColor.BLUE).create())
true true
} else { } else if (world == null){
sender.spigot().sendMessage(*ComponentBuilder("World ").color(ChatColor.RED) sender.spigot().sendMessage(*ComponentBuilder("World ").color(ChatColor.RED)
.append(worldName).color(ChatColor.GREEN).append(" not found!").color(ChatColor.RED).create()) .append(worldName).color(ChatColor.GREEN).append(" not found!").color(ChatColor.RED).create())
false false
} else {
sender.spigot().sendMessage(*ComponentBuilder("Task already exists!").color(ChatColor.RED).create())
return false
} }
} }
} }

@ -12,6 +12,13 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
val tasks: HashSet<RunningTaskEntry> = HashSet() val tasks: HashSet<RunningTaskEntry> = HashSet()
val pausedTasks: HashSet<PausedTaskEntry> = HashSet() val pausedTasks: HashSet<PausedTaskEntry> = HashSet()
val allTasks: HashSet<TaskEntry>
get() {
val all = HashSet<TaskEntry>()
all.addAll(pausedTasks)
all.addAll(tasks)
return all
}
var paused = false var paused = false
private set private set
@ -19,41 +26,51 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
* Adds a generation task * Adds a generation task
*/ */
fun addTask(world: World, stopAfter: Int = -1): Int { fun addTask(world: World, stopAfter: Int = -1): Int {
val centerChunk = world.getChunkAt(world.spawnLocation) val foundTask = allTasks.find { it.generationTask.world == world }
val generationTask = createGenerationTask(world, centerChunk, centerChunk, stopAfter) if (foundTask == null) {
val centerChunk = world.getChunkAt(world.spawnLocation)
val generationTask = createGenerationTask(world, centerChunk, centerChunk, stopAfter)
val insertStatement = chunkmaster.sqliteConnection.prepareStatement(""" val insertStatement = chunkmaster.sqliteConnection.prepareStatement("""
INSERT INTO generation_tasks (center_x, center_z, last_x, last_z, world, stop_after) INSERT INTO generation_tasks (center_x, center_z, last_x, last_z, world, stop_after)
values (?, ?, ?, ?, ?, ?) values (?, ?, ?, ?, ?, ?)
""") """)
insertStatement.setInt(1, centerChunk.x) insertStatement.setInt(1, centerChunk.x)
insertStatement.setInt(2, centerChunk.z) insertStatement.setInt(2, centerChunk.z)
insertStatement.setInt(3, centerChunk.x) insertStatement.setInt(3, centerChunk.x)
insertStatement.setInt(4, centerChunk.z) insertStatement.setInt(4, centerChunk.z)
insertStatement.setString(5, world.name) insertStatement.setString(5, world.name)
insertStatement.setInt(6, stopAfter) insertStatement.setInt(6, stopAfter)
insertStatement.execute() insertStatement.execute()
val getIdStatement = chunkmaster.sqliteConnection.prepareStatement(""" val getIdStatement = chunkmaster.sqliteConnection.prepareStatement("""
SELECT id FROM generation_tasks ORDER BY id DESC LIMIT 1 SELECT id FROM generation_tasks ORDER BY id DESC LIMIT 1
""".trimIndent()) """.trimIndent())
getIdStatement.execute() getIdStatement.execute()
val result = getIdStatement.resultSet val result = getIdStatement.resultSet
result.next() result.next()
val id: Int = result.getInt("id") val id: Int = result.getInt("id")
insertStatement.close() insertStatement.close()
getIdStatement.close() getIdStatement.close()
if (!paused) { generationTask.onEndReached {
val task = server.scheduler.runTaskTimer(chunkmaster, generationTask, 10, server.consoleSender.sendMessage("Task #${id} finished after ${generationTask.count} chunks.")
chunkmaster.config.getLong("generation.period")) removeTask(id)
tasks.add(RunningTaskEntry(id, task, generationTask)) }
if (!paused) {
val task = server.scheduler.runTaskTimer(chunkmaster, generationTask, 10,
chunkmaster.config.getLong("generation.period"))
tasks.add(RunningTaskEntry(id, task, generationTask))
} else {
pausedTasks.add(PausedTaskEntry(id, generationTask))
}
return id
} else { } else {
pausedTasks.add(PausedTaskEntry(id, generationTask)) return foundTask.id
} }
return id
} }
/** /**
@ -66,6 +83,10 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
val task = server.scheduler.runTaskTimer(chunkmaster, generationTask, 10, val task = server.scheduler.runTaskTimer(chunkmaster, generationTask, 10,
chunkmaster.config.getLong("generation.period")) chunkmaster.config.getLong("generation.period"))
tasks.add(RunningTaskEntry(id, task, generationTask)) tasks.add(RunningTaskEntry(id, task, generationTask))
generationTask.onEndReached {
server.consoleSender.sendMessage("Task #${id} finished after ${generationTask.count} chunks.")
removeTask(id)
}
} }
} }
@ -201,11 +222,6 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
updateStatement.setInt(3, task.id) updateStatement.setInt(3, task.id)
updateStatement.execute() updateStatement.execute()
updateStatement.close() updateStatement.close()
if (genTask.endReached) { // remove the task if it is finished after the progress has been saved
server.consoleSender.sendMessage("Task #${task.id} finished after ${genTask.count} chunks.")
removeTask(task.id)
}
} catch (error: Exception) { } catch (error: Exception) {
server.consoleSender.sendMessage("Exception when saving task progress ${error.message}") server.consoleSender.sendMessage("Exception when saving task progress ${error.message}")
} }

@ -23,6 +23,9 @@ abstract class GenerationTask(plugin: Chunkmaster, centerChunk: Chunk, startChun
protected val msptThreshold = plugin.config.getLong("generation.mspt-pause-threshold") protected val msptThreshold = plugin.config.getLong("generation.mspt-pause-threshold")
protected val maxLoadedChunks = plugin.config.getInt("generation.max-loaded-chunks") protected val maxLoadedChunks = plugin.config.getInt("generation.max-loaded-chunks")
protected var endReachedCallback: (() -> Unit)? = null
private set
abstract override fun run() abstract override fun run()
abstract fun cancel() abstract fun cancel()
@ -48,4 +51,11 @@ abstract class GenerationTask(plugin: Chunkmaster, centerChunk: Chunk, startChun
protected fun borderReached(): Boolean { protected fun borderReached(): Boolean {
return !world.worldBorder.isInside(lastChunkCoords.getCenterLocation(world)) || (stopAfter in 1..count) return !world.worldBorder.isInside(lastChunkCoords.getCenterLocation(world)) || (stopAfter in 1..count)
} }
/**
* Registers end reached callback
*/
fun onEndReached(cb: () -> Unit) {
endReachedCallback = cb
}
} }

@ -38,6 +38,7 @@ class GenerationTaskPaper(
} else if (pendingChunks.size < maxPendingChunks) { // if more than 10 chunks are pending, wait. } else if (pendingChunks.size < maxPendingChunks) { // if more than 10 chunks are pending, wait.
if (borderReached()) { if (borderReached()) {
endReached = true endReached = true
endReachedCallback?.invoke()
return return
} }

@ -33,6 +33,7 @@ class GenerationTaskSpigot(
} else { } else {
if (borderReached()) { if (borderReached()) {
endReached = true endReached = true
endReachedCallback?.invoke()
return return
} }

Loading…
Cancel
Save