RejectedExecutionException in WebserverManager.stop()
grote opened this issue · 3 comments
java.util.concurrent.RejectedExecutionException:
at io.netty.util.concurrent.SingleThreadEventExecutor.reject (SingleThreadEventExecutor.java:923)
at io.netty.util.concurrent.SingleThreadEventExecutor.offerTask (SingleThreadEventExecutor.java:350)
at io.netty.util.concurrent.SingleThreadEventExecutor.addTask (SingleThreadEventExecutor.java:343)
at io.netty.util.concurrent.SingleThreadEventExecutor.execute (SingleThreadEventExecutor.java:825)
at io.netty.util.concurrent.SingleThreadEventExecutor.execute (SingleThreadEventExecutor.java:815)
at io.netty.channel.AbstractChannelHandlerContext.safeExecute (AbstractChannelHandlerContext.java:989)
at io.netty.channel.AbstractChannelHandlerContext.close (AbstractChannelHandlerContext.java:608)
at io.netty.channel.AbstractChannelHandlerContext.close (AbstractChannelHandlerContext.java:472)
at io.netty.channel.DefaultChannelPipeline.close (DefaultChannelPipeline.java:957)
at io.netty.channel.AbstractChannel.close (AbstractChannel.java:244)
at io.ktor.server.netty.NettyApplicationEngine.stop (NettyApplicationEngine.kt:202)
at org.onionshare.android.server.WebserverManager.stop (WebserverManager.kt:75)
at org.onionshare.android.ShareManager$stopSharing$2.invokeSuspend (ShareManager.kt:191)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run (DispatchedTask.kt:106)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely (CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask (CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker (CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run (CoroutineScheduler.kt:665)
Maybe the executor was already shut down or something like that? Is it safe it just catch and ignore this exception?
In Briar we use ThreadPoolExecutor.DiscardPolicy when creating our executors so that tasks submitted during app shutdown are discarded. I guess Netty is creating its own executor here so maybe we don't have control over the RejectedExecutionPolicy. Perhaps we can defer stopping the web server until all IO tasks have finished? Note sure how to achieve that though.
https://stackoverflow.com/questions/29109889/android-netty-rejectedexecutionexception
Upstream ticket that looks related although here it happens when restarting the server: https://youtrack.jetbrains.com/issue/KTOR-2762/Cannot-properly-restart-a-server
I tried stopping the server while a download was running and got only an expected exception logged with debug level, but not RejectedExecutionException
. When the server is restarted, we use a new instance, so maybe we should just catch the exception and null the reference to the old server. If it doesn't execute stuff anymore, maybe it will get GCed and there's no issue as we won't be using it anymore anyway?