You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm using Ktor, which is based on coroutines. This seems to be conflicting with the thread manager that the Google Maps Platform Java library uses. It keeps giving me an Unexpected exception from com.google.apphosting.api.ApiProxy$CallNotFoundException: Can't make API call urlfetch.Fetch in a thread that is neither the original request thread nor a thread created by ThreadManager error.
Environment details
Specify the API at the beginning of the title (for example, "Places: ...")
OS type and version
Library version and other environment information
Places Autocomplete
Kotlin 1.4
0.11.0
Steps to reproduce
Make a request to PlacesApi.placeAutocomplete(context, query, null).await()
Code example
fun Application.placesAutocomplete() {
routing {
get("/v1/places/autocomplete") {
val parameters = call.request.queryParameters
val query:String?= parameters["query"]
val type:String?= parameters["type"]
if (query ==null) {
call.respondParameterRequired("query")
return@get
}
if (query.isBlank()) {
call.respond(AutocompleteResponse(emptyList()))
return@get
}
valPLACES_KEY=System.getenv("PLACES_KEY")
val placeAutocompleteTypes =try {
type?.let { PlaceAutocompleteType.valueOf(type) }
} catch (e:IllegalArgumentException) {
call.respond(HttpStatusCode.BadRequest, "Invalid place type")
return@get
}
val context =GeoApiContext.Builder(GaeRequestHandler.Builder()).apiKey(PLACES_KEY).build()
val placeAutocompleteRequest =PlacesApi.placeAutocomplete(context, query, null)
placeAutocompleteTypes?.let { types ->
placeAutocompleteRequest.types(types)
}
try {
val placeAutocompleteResponse = withContext(Dispatchers.IO) { placeAutocompleteRequest.await() }
val places = placeAutocompleteResponse.map {
val formatting = it.structuredFormatting
Place(
placeId = it.placeId, mainText = formatting.mainText
?:"", secondaryText = formatting.secondaryText
?:""
)
}
val autocompleteResponse =AutocompleteResponse(places)
call.respond(autocompleteResponse)
} catch (e:Exception) {
call.respond(HttpStatusCode.InternalServerError, e)
}
}
}
}
Stack trace
com.google.maps.errors.UnknownErrorException: Unexpected exception from com.google.apphosting.api.ApiProxy$CallNotFoundException: Can't make API call urlfetch.Fetch in a thread that is neither the original request thread nor a thread created by ThreadManager
at com.google.maps.internal.GaePendingResult.await(GaePendingResult.java:121)
at com.google.maps.PendingResultBase.await(PendingResultBase.java:58)
at appengine.PlacesAutocompleteKt$placesAutocomplete$1$1$placeAutocompleteResponse$1.invokeSuspend(PlacesAutocomplete.kt:74)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:272)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:79)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:54)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:36)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
at appengine.PlacesAutocompleteKt$placesAutocomplete$1$1.invokeSuspend(PlacesAutocomplete.kt:74)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:175)
at kotlinx.coroutines.DispatchedTaskKt.resumeUnconfined(DispatchedTask.kt:137)
at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:108)
at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:307)
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:317)
at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:249)
at retrofit2.KotlinExtensions$awaitResponse$2$2.onResponse(KotlinExtensions.kt:93)
at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:129)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
The text was updated successfully, but these errors were encountered:
Hi @mochat97, based on the stacktrace you shared, you will need to create the full request object (specifically the GeoApiContext which creates a OkHttpRequestHandler internally) inside the coroutine scope where the request is invoked.
So:
try {
val placeAutocompleteResponse = withContext(Dispatchers.IO) {
val context =GeoApiContext.Builder(GaeRequestHandler.Builder()).apiKey(PLACES_KEY).build()
val placeAutocompleteRequest =PlacesApi.placeAutocomplete(context, query, null)
placeAutocompleteTypes?.let { types ->
placeAutocompleteRequest.types(types)
}
placeAutocompleteRequest.await()
}
I'm not very familiar with Ktor but seems like the only solution here would be to create a custom Dispatcher (instead of Dispatchers.IO) that pulls new threads from ThreadManager.
As a HTTP GET request is synchronous by nature, do you need to spawn a new coroutine at the point you are in the code causing the issue? I believe the solution would be to implement asynchronous behaviour in your client.
I'm using Ktor, which is based on coroutines. This seems to be conflicting with the thread manager that the Google Maps Platform Java library uses. It keeps giving me an
Unexpected exception from com.google.apphosting.api.ApiProxy$CallNotFoundException: Can't make API call urlfetch.Fetch in a thread that is neither the original request thread nor a thread created by ThreadManager
error.Environment details
Places Autocomplete
Kotlin 1.4
0.11.0
Steps to reproduce
PlacesApi.placeAutocomplete(context, query, null).await()
Code example
Stack trace
The text was updated successfully, but these errors were encountered: