Add delay to starting of generation tasks

Add a delay to the starts of the tasks so that they don't all start on the same tick. To completely avoid two tasks being executed on the same tick, the "period" config option should be set to the expected number of tasks or higher.
pull/29/head
trivernis 5 years ago
parent 6cb39ce843
commit ecc3165f1f

@ -2,6 +2,7 @@ package net.trivernis.chunkmaster.lib.generation
import io.papermc.lib.PaperLib import io.papermc.lib.PaperLib
import net.trivernis.chunkmaster.Chunkmaster import net.trivernis.chunkmaster.Chunkmaster
import org.bukkit.Chunk
import org.bukkit.Server import org.bukkit.Server
import org.bukkit.World import org.bukkit.World
@ -83,13 +84,14 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
center: ChunkCoordinates, center: ChunkCoordinates,
last: ChunkCoordinates, last: ChunkCoordinates,
id: Int, id: Int,
stopAfter: Int = -1 stopAfter: Int = -1,
delay: Long = 200L
) { ) {
if (!paused) { if (!paused) {
chunkmaster.logger.info(chunkmaster.langManager.getLocalized("RESUME_FOR_WORLD", world.name)) chunkmaster.logger.info(chunkmaster.langManager.getLocalized("RESUME_FOR_WORLD", world.name))
val generationTask = createGenerationTask(world, center, last, stopAfter) val generationTask = createGenerationTask(world, center, last, stopAfter)
val task = server.scheduler.runTaskTimer( val task = server.scheduler.runTaskTimer(
chunkmaster, generationTask, 200, // 10 sec delay chunkmaster, generationTask, delay, // 10 sec delay
chunkmaster.config.getLong("generation.period") chunkmaster.config.getLong("generation.period")
) )
tasks.add(RunningTaskEntry(id, task, generationTask)) tasks.add(RunningTaskEntry(id, task, generationTask))
@ -149,11 +151,14 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
* Stops all generation tasks * Stops all generation tasks
*/ */
fun stopAll() { fun stopAll() {
saveProgress()
val removalSet = HashSet<RunningTaskEntry>() val removalSet = HashSet<RunningTaskEntry>()
for (task in tasks) { for (task in tasks) {
task.generationTask.cancel() val lastChunk = task.generationTask.lastChunkCoords
val id = task.id
chunkmaster.logger.info(chunkmaster.langManager.getLocalized("SAVING_TASK_PROGRESS", task.id))
saveProgressToDatabase(lastChunk, id)
task.task.cancel() task.task.cancel()
task.generationTask.cancel()
if (task.task.isCancelled) { if (task.task.isCancelled) {
removalSet.add(task) removalSet.add(task)
} }
@ -167,7 +172,9 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
*/ */
fun startAll() { fun startAll() {
chunkmaster.sqliteManager.executeStatement("SELECT * FROM generation_tasks", HashMap()) { res -> chunkmaster.sqliteManager.executeStatement("SELECT * FROM generation_tasks", HashMap()) { res ->
var count = 0
while (res.next()) { while (res.next()) {
count++
try { try {
val id = res.getInt("id") val id = res.getInt("id")
val world = server.getWorld(res.getString("world")) val world = server.getWorld(res.getString("world"))
@ -175,7 +182,7 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
val last = ChunkCoordinates(res.getInt("last_x"), res.getInt("last_z")) val last = ChunkCoordinates(res.getInt("last_x"), res.getInt("last_z"))
val stopAfter = res.getInt("stop_after") val stopAfter = res.getInt("stop_after")
if (this.tasks.find { it.id == id } == null) { if (this.tasks.find { it.id == id } == null) {
resumeTask(world!!, center, last, id, stopAfter) resumeTask(world!!, center, last, id, stopAfter, 200L + count)
} }
} catch (error: NullPointerException) { } catch (error: NullPointerException) {
chunkmaster.logger.severe(chunkmaster.langManager.getLocalized("TASK_LOAD_FAILED", res.getInt("id"))) chunkmaster.logger.severe(chunkmaster.langManager.getLocalized("TASK_LOAD_FAILED", res.getInt("id")))
@ -238,20 +245,27 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
speed, speed,
genTask.lastChunk.x, genTask.lastChunk.x,
genTask.lastChunk.z)) genTask.lastChunk.z))
chunkmaster.sqliteManager.executeStatement( saveProgressToDatabase(genTask.lastChunkCoords, task.id)
"""
UPDATE generation_tasks SET last_x = ?, last_z = ?
WHERE id = ?
""".trimIndent(),
HashMap(mapOf(1 to genTask.lastChunk.x, 2 to genTask.lastChunk.z, 3 to task.id)),
null
)
} catch (error: Exception) { } catch (error: Exception) {
chunkmaster.logger.warning(chunkmaster.langManager.getLocalized("TASK_SAVE_FAILED", error.toString())) chunkmaster.logger.warning(chunkmaster.langManager.getLocalized("TASK_SAVE_FAILED", error.toString()))
} }
} }
} }
/**
* Saves the generation progress to the database
*/
private fun saveProgressToDatabase(lastChunk: ChunkCoordinates, id: Int) {
chunkmaster.sqliteManager.executeStatement(
"""
UPDATE generation_tasks SET last_x = ?, last_z = ?
WHERE id = ?
""".trimIndent(),
HashMap(mapOf(1 to lastChunk.x, 2 to lastChunk.z, 3 to id)),
null
)
}
/** /**
* Creates a new generation task. This method is used to create a task depending * Creates a new generation task. This method is used to create a task depending
* on the server type (Paper/Spigot). * on the server type (Paper/Spigot).

@ -17,7 +17,8 @@ abstract class GenerationTask(plugin: Chunkmaster, centerChunk: ChunkCoordinates
protected val spiral: Spiral = protected val spiral: Spiral =
Spiral(Pair(centerChunk.x, centerChunk.z), Pair(startChunk.x, startChunk.z)) Spiral(Pair(centerChunk.x, centerChunk.z), Pair(startChunk.x, startChunk.z))
protected val loadedChunks: HashSet<Chunk> = HashSet() protected val loadedChunks: HashSet<Chunk> = HashSet()
protected var lastChunkCoords = ChunkCoordinates(startChunk.x, startChunk.z) var lastChunkCoords = ChunkCoordinates(startChunk.x, startChunk.z)
protected set
protected val chunkSkips = plugin.config.getInt("generation.chunk-skips-per-step") protected val chunkSkips = plugin.config.getInt("generation.chunk-skips-per-step")
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")

@ -2,6 +2,7 @@ package net.trivernis.chunkmaster.lib.generation
import net.trivernis.chunkmaster.Chunkmaster import net.trivernis.chunkmaster.Chunkmaster
import org.bukkit.World import org.bukkit.World
import java.lang.Exception
class GenerationTaskSpigot( class GenerationTaskSpigot(
private val plugin: Chunkmaster, override val world: World, private val plugin: Chunkmaster, override val world: World,
@ -62,7 +63,11 @@ class GenerationTaskSpigot(
override fun cancel() { override fun cancel() {
for (chunk in loadedChunks) { for (chunk in loadedChunks) {
if (chunk.isLoaded) { if (chunk.isLoaded) {
chunk.unload(true) try {
chunk.unload(true)
} catch (e: Exception) {
plugin.logger.severe(e.toString())
}
} }
} }
} }

@ -35,6 +35,7 @@ NO_PERMISSION = §cYou do not have the permission for this command!
SUBCOMMAND_NOT_FOUND = §cSubcommand §2%s §cnot found! SUBCOMMAND_NOT_FOUND = §cSubcommand §2%s §cnot found!
STOPPING_ALL_TASKS = Stopping all generation tasks... STOPPING_ALL_TASKS = Stopping all generation tasks...
SAVING_TASK_PROGRESS = Saving the progress of task #%s to the database...
DB_INIT = Initializing database... DB_INIT = Initializing database...
DB_INIT_FINISHED = Database fully initialized. DB_INIT_FINISHED = Database fully initialized.
DB_INIT_EROR = Failed to init database: %s. DB_INIT_EROR = Failed to init database: %s.

@ -35,6 +35,7 @@ NO_PERMISSION = §cDu hast nicht die Rechte für diesen Befehl!
SUBCOMMAND_NOT_FOUND = §cUnteraktion §2%s §cwurde nicht gefunden! SUBCOMMAND_NOT_FOUND = §cUnteraktion §2%s §cwurde nicht gefunden!
STOPPING_ALL_TASKS = Stoppt alle Aufgaben... STOPPING_ALL_TASKS = Stoppt alle Aufgaben...
SAVING_TASK_PROGRESS = Speichert den Fortschritt der Aufgabe #%s in der Datenbank...
DB_INIT = Initialisiere Datenbank... DB_INIT = Initialisiere Datenbank...
DB_INIT_FINISHED = Die Datenbank wurde initialisiert. DB_INIT_FINISHED = Die Datenbank wurde initialisiert.
DB_INIT_EROR = Fehler beim Initalisieren der Datenbank: %s. DB_INIT_EROR = Fehler beim Initalisieren der Datenbank: %s.

@ -35,6 +35,7 @@ NO_PERMISSION = §cYou do not have the permission for this command!
SUBCOMMAND_NOT_FOUND = §cSubcommand §2%s §cnot found! SUBCOMMAND_NOT_FOUND = §cSubcommand §2%s §cnot found!
STOPPING_ALL_TASKS = Stopping all generation tasks... STOPPING_ALL_TASKS = Stopping all generation tasks...
SAVING_TASK_PROGRESS = Saving the progress of task #%s to the database...
DB_INIT = Initializing database... DB_INIT = Initializing database...
DB_INIT_FINISHED = Database fully initialized. DB_INIT_FINISHED = Database fully initialized.
DB_INIT_EROR = Failed to init database: %s. DB_INIT_EROR = Failed to init database: %s.

Loading…
Cancel
Save