diff options
author | Dico Karssiens <dico.karssiens@gmail.com> | 2018-07-30 13:57:39 +0100 |
---|---|---|
committer | Dico Karssiens <dico.karssiens@gmail.com> | 2018-07-30 13:57:39 +0100 |
commit | 48da05c9e866cbdfa3bdedb7d3ae35201993bf14 (patch) | |
tree | 49f23489d2afdd11aa522ff40a3d0af9d0580906 | |
parent | ee287253d6e29e8fa30c82674337ca4a962bb1d7 (diff) |
Add passthrough for exceptions
-rw-r--r-- | src/main/kotlin/io/dico/parcels2/ParcelsPlugin.kt | 2 | ||||
-rw-r--r-- | src/main/kotlin/io/dico/parcels2/blockvisitor/WorktimeLimiter.kt | 34 |
2 files changed, 28 insertions, 8 deletions
diff --git a/src/main/kotlin/io/dico/parcels2/ParcelsPlugin.kt b/src/main/kotlin/io/dico/parcels2/ParcelsPlugin.kt index 8f0e89e..689a534 100644 --- a/src/main/kotlin/io/dico/parcels2/ParcelsPlugin.kt +++ b/src/main/kotlin/io/dico/parcels2/ParcelsPlugin.kt @@ -31,7 +31,7 @@ class ParcelsPlugin : JavaPlugin() { lateinit var entityTracker: ParcelEntityTracker; private set private var listeners: ParcelListeners? = null private var cmdDispatcher: ICommandDispatcher? = null - val worktimeLimiter: WorktimeLimiter by lazy { TickWorktimeLimiter(this, options) } + val worktimeLimiter: WorktimeLimiter by lazy { TickWorktimeLimiter(this, options.tickWorktime) } override fun onEnable() { plogger.info("Debug enabled: ${plogger.isDebugEnabled}") diff --git a/src/main/kotlin/io/dico/parcels2/blockvisitor/WorktimeLimiter.kt b/src/main/kotlin/io/dico/parcels2/blockvisitor/WorktimeLimiter.kt index 0eca6c9..45196f2 100644 --- a/src/main/kotlin/io/dico/parcels2/blockvisitor/WorktimeLimiter.kt +++ b/src/main/kotlin/io/dico/parcels2/blockvisitor/WorktimeLimiter.kt @@ -6,6 +6,7 @@ import org.bukkit.scheduler.BukkitTask import java.lang.System.currentTimeMillis import java.util.* import java.util.concurrent.Executor +import java.util.logging.Level import kotlin.coroutines.experimental.Continuation import kotlin.coroutines.experimental.intrinsics.COROUTINE_SUSPENDED import kotlin.coroutines.experimental.intrinsics.suspendCoroutineUninterceptedOrReturn @@ -47,6 +48,12 @@ interface Worker : Timed { val isComplete: Boolean /** + * If an exception was thrown during the execution of this task, + * returns that exception. Returns null otherwise. + */ + val completionException: Throwable? + + /** * A value indicating the progress of this worker, in the range 0.0 <= progress <= 1.0 * with no guarantees to its accuracy. May be null. */ @@ -104,7 +111,7 @@ class TickWorktimeLimiter(private val plugin: Plugin, var options: TickWorktimeO override val workers: List<Worker> = _workers override fun submit(task: TimeLimitedTask): Worker { - val worker: WorkerContinuation = WorkerImpl(dispatcher, task) + val worker: WorkerContinuation = WorkerImpl(plugin, dispatcher, task) _workers.addFirst(worker) if (bukkitTask == null) bukkitTask = plugin.server.scheduler.runTaskTimer(plugin, ::tickJobs, 0, options.tickInterval.toLong()) return worker @@ -122,7 +129,7 @@ class TickWorktimeLimiter(private val plugin: Plugin, var options: TickWorktimeO val timeLeft = options.workTime - timeElapsed if (timeLeft <= 0) return - val count = iterator.nextIndex() + val count = workers.size - iterator.nextIndex() val timePerJob = (timeLeft + count - 1) / count val worker = iterator.next() val completed = worker.resume(timePerJob) @@ -139,7 +146,8 @@ class TickWorktimeLimiter(private val plugin: Plugin, var options: TickWorktimeO } -private class WorkerImpl(val dispatcher: CoroutineDispatcher, +private class WorkerImpl(val plugin: Plugin, + val dispatcher: CoroutineDispatcher, val task: TimeLimitedTask) : WorkerContinuation { override var job: Job? = null; private set @@ -151,6 +159,8 @@ private class WorkerImpl(val dispatcher: CoroutineDispatcher, override val isComplete get() = job?.isCompleted == true + override var completionException: Throwable? = null; private set + override var progress: Double? = null; private set private var startTimeOrElapsedTime: Long = 0L // startTime before completed, elapsed time otherwise @@ -165,7 +175,13 @@ private class WorkerImpl(val dispatcher: CoroutineDispatcher, this.job?.let { throw IllegalStateException() } this.job = job startTimeOrElapsedTime = System.currentTimeMillis() - job.invokeOnCompletion { + job.invokeOnCompletion { exception -> + // report any error that occurred + completionException = exception?.also { + if (it !is CancellationException) + plugin.logger.log(Level.SEVERE, "TimeLimitedTask for plugin ${plugin.name} generated an exception", it) + } + // convert to elapsed time here startTimeOrElapsedTime = System.currentTimeMillis() - startTimeOrElapsedTime onCompleted?.let { it(1.0, elapsedTime) } @@ -219,9 +235,13 @@ private class WorkerImpl(val dispatcher: CoroutineDispatcher, throw IllegalStateException() } - launch(context = dispatcher, start = CoroutineStart.UNDISPATCHED) { - initJob(job = kotlin.coroutines.experimental.coroutineContext[Job]!!) - task() + try { + launch(context = dispatcher, start = CoroutineStart.UNDISPATCHED) { + initJob(job = kotlin.coroutines.experimental.coroutineContext[Job]!!) + task() + } + } catch (t: Throwable) { + // do nothing: handled by job.invokeOnCompletion() } return continuation == null |