Skip to content

Commit

Permalink
add: auto-cancel deferred task if completed before
Browse files Browse the repository at this point in the history
  • Loading branch information
ShindouMihou committed Feb 24, 2023
1 parent 60e0ac1 commit f20a59e
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ class NexusLaunchConfiguration internal constructor() {
NexusThreadPool.executorService.submit { task.run() }
}
@JvmField var scheduler: NexusScheduledLaunchWrapper = NexusScheduledLaunchWrapper { timeInMillis, task ->
NexusThreadPool.scheduledExecutorService.schedule(task::run, timeInMillis, TimeUnit.MILLISECONDS)
return@NexusScheduledLaunchWrapper object: Cancellable {
val scheduledTask = NexusThreadPool.scheduledExecutorService.schedule(task::run, timeInMillis, TimeUnit.MILLISECONDS)
override fun cancel(mayInterruptIfRunning: Boolean): Boolean {
return scheduledTask.cancel(mayInterruptIfRunning)
}
}
}
}

Expand All @@ -17,7 +22,11 @@ fun interface NexusLaunchWrapper {
}

fun interface NexusScheduledLaunchWrapper {
fun launch(timeInMillis: Long, task: NexusLaunchTask)
fun launch(timeInMillis: Long, task: NexusLaunchTask): Cancellable
}

interface Cancellable {
fun cancel(mayInterruptIfRunning: Boolean): Boolean
}

fun interface NexusLaunchTask {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,20 @@ object NexusCommandDispatcher {
}
val timeUntil = Instant.now().toEpochMilli() -
event.interaction.creationTimestamp.minusMillis(Nexus.configuration.global.autoDeferAfterMilliseconds).toEpochMilli()
Nexus.launch.scheduler.launch(timeUntil) {
val deferredTaskRan = AtomicBoolean(false)
val task = Nexus.launch.scheduler.launch(timeUntil) {
deferredTaskRan.set(true)
if (future.isDone) {
return@launch
}
nexusEvent.respondLaterAsEphemeralIf(Nexus.configuration.interceptors.autoDeferAsEphemeral)
.exceptionally(ExceptionLogger.get())
}
future.join()
val gate = future.join()
if (!deferredTaskRan.get()) {
task.cancel(false)
}
gate
} else {
NexusCommandInterceptorCore.execute(nexusEvent, NexusCommandInterceptorCore.middlewares(middlewares))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import org.javacord.api.event.interaction.SlashCommandCreateEvent
import org.javacord.api.interaction.callback.InteractionOriginalResponseUpdater
import org.javacord.api.util.logging.ExceptionLogger
import pw.mihou.nexus.Nexus
import pw.mihou.nexus.configuration.modules.Cancellable
import pw.mihou.nexus.features.command.facade.NexusCommand
import pw.mihou.nexus.features.command.facade.NexusCommandEvent
import pw.mihou.nexus.features.command.responses.NexusAutoResponse
import pw.mihou.nexus.features.messages.NexusMessage
import java.time.Instant
import java.util.concurrent.CompletableFuture
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicReference
import java.util.function.Function

Expand All @@ -22,22 +24,31 @@ class NexusCommandEventCore(private val event: SlashCommandCreateEvent, private
override fun getCommand() = command
override fun store() = store
override fun autoDefer(ephemeral: Boolean, response: Function<Void?, NexusMessage>): CompletableFuture<NexusAutoResponse> {
var task: Cancellable? = null
val deferredTaskRan = AtomicBoolean(false)
if (updater.get() == null) {
val timeUntil = Instant.now().toEpochMilli() - event.interaction.creationTimestamp
.minusMillis(Nexus.configuration.global.autoDeferAfterMilliseconds)
.toEpochMilli()

Nexus.launch.scheduler.launch(timeUntil) {
task = Nexus.launch.scheduler.launch(timeUntil) {
if (updater.get() == null) {
respondLaterAsEphemeralIf(ephemeral).exceptionally(ExceptionLogger.get())
}
deferredTaskRan.set(true)
}
}
val future = CompletableFuture<NexusAutoResponse>()
Nexus.launcher.launch {
try {
val message = response.apply(null)
val updater = updater.get()
if (!deferredTaskRan.get() && task != null) {
task.cancel(false)
}
val updater = respondLaterAsEphemeralIf(ephemeral).exceptionally {
future.completeExceptionally(it)
return@exceptionally null
}
if (updater == null) {
val responder = respondNow()
if (ephemeral) {
Expand Down

0 comments on commit f20a59e

Please sign in to comment.