Add passthrough for exceptions
This commit is contained in:
@@ -31,7 +31,7 @@ class ParcelsPlugin : JavaPlugin() {
|
|||||||
lateinit var entityTracker: ParcelEntityTracker; private set
|
lateinit var entityTracker: ParcelEntityTracker; private set
|
||||||
private var listeners: ParcelListeners? = null
|
private var listeners: ParcelListeners? = null
|
||||||
private var cmdDispatcher: ICommandDispatcher? = 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() {
|
override fun onEnable() {
|
||||||
plogger.info("Debug enabled: ${plogger.isDebugEnabled}")
|
plogger.info("Debug enabled: ${plogger.isDebugEnabled}")
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import org.bukkit.scheduler.BukkitTask
|
|||||||
import java.lang.System.currentTimeMillis
|
import java.lang.System.currentTimeMillis
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.Executor
|
import java.util.concurrent.Executor
|
||||||
|
import java.util.logging.Level
|
||||||
import kotlin.coroutines.experimental.Continuation
|
import kotlin.coroutines.experimental.Continuation
|
||||||
import kotlin.coroutines.experimental.intrinsics.COROUTINE_SUSPENDED
|
import kotlin.coroutines.experimental.intrinsics.COROUTINE_SUSPENDED
|
||||||
import kotlin.coroutines.experimental.intrinsics.suspendCoroutineUninterceptedOrReturn
|
import kotlin.coroutines.experimental.intrinsics.suspendCoroutineUninterceptedOrReturn
|
||||||
@@ -46,6 +47,12 @@ interface Worker : Timed {
|
|||||||
*/
|
*/
|
||||||
val isComplete: Boolean
|
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
|
* 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.
|
* 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 val workers: List<Worker> = _workers
|
||||||
|
|
||||||
override fun submit(task: TimeLimitedTask): Worker {
|
override fun submit(task: TimeLimitedTask): Worker {
|
||||||
val worker: WorkerContinuation = WorkerImpl(dispatcher, task)
|
val worker: WorkerContinuation = WorkerImpl(plugin, dispatcher, task)
|
||||||
_workers.addFirst(worker)
|
_workers.addFirst(worker)
|
||||||
if (bukkitTask == null) bukkitTask = plugin.server.scheduler.runTaskTimer(plugin, ::tickJobs, 0, options.tickInterval.toLong())
|
if (bukkitTask == null) bukkitTask = plugin.server.scheduler.runTaskTimer(plugin, ::tickJobs, 0, options.tickInterval.toLong())
|
||||||
return worker
|
return worker
|
||||||
@@ -122,7 +129,7 @@ class TickWorktimeLimiter(private val plugin: Plugin, var options: TickWorktimeO
|
|||||||
val timeLeft = options.workTime - timeElapsed
|
val timeLeft = options.workTime - timeElapsed
|
||||||
if (timeLeft <= 0) return
|
if (timeLeft <= 0) return
|
||||||
|
|
||||||
val count = iterator.nextIndex()
|
val count = workers.size - iterator.nextIndex()
|
||||||
val timePerJob = (timeLeft + count - 1) / count
|
val timePerJob = (timeLeft + count - 1) / count
|
||||||
val worker = iterator.next()
|
val worker = iterator.next()
|
||||||
val completed = worker.resume(timePerJob)
|
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 {
|
val task: TimeLimitedTask) : WorkerContinuation {
|
||||||
override var job: Job? = null; private set
|
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 val isComplete get() = job?.isCompleted == true
|
||||||
|
|
||||||
|
override var completionException: Throwable? = null; private set
|
||||||
|
|
||||||
override var progress: Double? = null; private set
|
override var progress: Double? = null; private set
|
||||||
|
|
||||||
private var startTimeOrElapsedTime: Long = 0L // startTime before completed, elapsed time otherwise
|
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?.let { throw IllegalStateException() }
|
||||||
this.job = job
|
this.job = job
|
||||||
startTimeOrElapsedTime = System.currentTimeMillis()
|
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
|
// convert to elapsed time here
|
||||||
startTimeOrElapsedTime = System.currentTimeMillis() - startTimeOrElapsedTime
|
startTimeOrElapsedTime = System.currentTimeMillis() - startTimeOrElapsedTime
|
||||||
onCompleted?.let { it(1.0, elapsedTime) }
|
onCompleted?.let { it(1.0, elapsedTime) }
|
||||||
@@ -219,9 +235,13 @@ private class WorkerImpl(val dispatcher: CoroutineDispatcher,
|
|||||||
throw IllegalStateException()
|
throw IllegalStateException()
|
||||||
}
|
}
|
||||||
|
|
||||||
launch(context = dispatcher, start = CoroutineStart.UNDISPATCHED) {
|
try {
|
||||||
initJob(job = kotlin.coroutines.experimental.coroutineContext[Job]!!)
|
launch(context = dispatcher, start = CoroutineStart.UNDISPATCHED) {
|
||||||
task()
|
initJob(job = kotlin.coroutines.experimental.coroutineContext[Job]!!)
|
||||||
|
task()
|
||||||
|
}
|
||||||
|
} catch (t: Throwable) {
|
||||||
|
// do nothing: handled by job.invokeOnCompletion()
|
||||||
}
|
}
|
||||||
|
|
||||||
return continuation == null
|
return continuation == null
|
||||||
|
|||||||
Reference in New Issue
Block a user