Cross-point from the <#C0A974TJ9|ktor> channel (<h...
# coroutines
r
e
Why are you creating an entire new thread pool here? You should just be able to write:
If you really need to use a different scope you can use
withContext() { }
e.g.
withContext(<http://Dispatchers.IO|Dispatchers.IO>) { }
r
I tried that too before. When I try:
Copy code
val oauthScope = "<scope>"
        val accessToken = AppIdentityServiceFactory.getAppIdentityService().getAccessToken(listOf(oauthScope))
        call.respondText {
            accessToken.accessToken
        }
I get this:
Copy code
SEVERE: Something bad happened
com.google.apphosting.api.ApiProxy$CallNotFoundException: Can't make API call memcache.Get in a thread that is neither the original request thread nor a thread created by ThreadManager
        at com.google.apphosting.api.ApiProxy$CallNotFoundException.foreignThread(ApiProxy.java:800)
        at com.google.apphosting.api.ApiProxy$1.get(ApiProxy.java:179)
        at com.google.apphosting.api.ApiProxy$1.get(ApiProxy.java:176)
        at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:89)
        at com.google.appengine.api.memcache.MemcacheServiceImpl.quietGet(MemcacheServiceImpl.java:26)
        at com.google.appengine.api.memcache.MemcacheServiceImpl.get(MemcacheServiceImpl.java:49)
        at com.google.appengine.api.appidentity.AppIdentityServiceImpl.getAccessToken(AppIdentityServiceImpl.java:288)
        at androidx.snapshots.RequestHandlersKt$main$3.invokeSuspend(RequestHandlers.kt:30)
My guess is that the request dispatch is actually happening on a
Thread
which was not created by
ThreadManager
at all
e
It’s possible that because coroutines may switch threads during execution you may hit a thread switch while the Ktor pipeline is running… I’m not really sure though
r
https://github.com/ktorio/ktor/issues/1486 I also found this, but I am not sure what this solution actually entails.
e
I’m not super familiar with app engine but I’ll give it a shot. So what that answer seems to be doing is creating a subclass of ServletApplicationEngine which I assume is the thing accepting app engine requests? The subclass then creates a single-threaded coroutine dispatcher to prevent thread switches so when you attempt to use anything that isn’t thread safe you should
withContext() { }
to that dispatcher
r
Let me give that a shot