无法在既不是原始请求线程也不是 ThreadManager 创建的线程的线程中 API 调用 urlfetch.Fetch

Can't make API call urlfetch.Fetch in a thread that is neither the original request thread nor a thread created by ThreadManager

我目前正在使用 kotlin、Spring 社交和 Google 应用引擎。我试图每秒恢复一些关注者。

这是我的代码:

@Service
class SubscribeService {
    var subscriber : Disposable? = null
    var twitter : Twitter = TwitterTemplate(
            "XXXAUTHXXX",
            "XXXAUTHXXX",
            "XXXAUTHXXX",
            "XXXAUTHXXX")

    fun subscribe() {
        subscriber = Observable.interval(1, TimeUnit.SECONDS).subscribe {println(twitter.userOperations().getUserProfile("azeaze").followersCount)}
    }

    fun unsubscribe() {
        subscriber?.dispose()
    }
}    

我在执行订阅功能时遇到此异常:

[INFO] io.reactivex.exceptions.OnErrorNotImplementedException: Can't make API call urlfetch.Fetch in a thread that is neither the original request thread nor a thread created by ThreadManager
[INFO]  at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704)
[INFO]  at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701)
[INFO]  at io.reactivex.internal.observers.LambdaObserver.onError(LambdaObserver.java:74)
[INFO]  at io.reactivex.internal.observers.LambdaObserver.onNext(LambdaObserver.java:64)
[INFO]  at io.reactivex.internal.operators.observable.ObservableInterval$IntervalObserver.run(ObservableInterval.java:83)
[INFO]  at io.reactivex.internal.schedulers.ScheduledDirectPeriodicTask.run(ScheduledDirectPeriodicTask.java:39)
[INFO]  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[INFO]  at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
[INFO]  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access1(ScheduledThreadPoolExecutor.java:180)
[INFO]  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
[INFO]  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
[INFO]  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
[INFO]  at java.lang.Thread.run(Thread.java:748)
[INFO] Caused by: 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
[INFO]  at com.google.apphosting.api.ApiProxy$CallNotFoundException.foreignThread(ApiProxy.java:844)
[INFO]  at com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:116)
[INFO]  at com.google.appengine.api.urlfetch.URLFetchServiceImpl.fetch(URLFetchServiceImpl.java:40)
[INFO]  at com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection.fetchResponse(URLFetchServiceStreamHandler.java:543)
[INFO]  at com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection.getInputStream(URLFetchServiceStreamHandler.java:422)
[INFO]  at com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection.getResponseCode(URLFetchServiceStreamHandler.java:275)
[INFO]  at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:84)
[INFO]  at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
[INFO]  at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
[INFO]  at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:99)
[INFO]  at org.springframework.social.oauth1.OAuth1RequestInterceptor.intercept(OAuth1RequestInterceptor.java:48)
[INFO]  at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:86)
[INFO]  at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:70)
[INFO]  at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
[INFO]  at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
[INFO]  at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:652)
[INFO]  at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:628)
[INFO]  at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:303)
[INFO]  at org.springframework.social.twitter.api.impl.UserTemplate.getUserProfile(UserTemplate.java:60)
[INFO]  at tbetous.SubscribeService$test.accept(SubscribeService.kt:20)
[INFO]  at tbetous.SubscribeService$test.accept(SubscribeService.kt:11)
[INFO]  at io.reactivex.internal.observers.LambdaObserver.onNext(LambdaObserver.java:60)
[INFO]  ... 9 more
[INFO] Exception in thread "RxComputationThreadPool-1" io.reactivex.exceptions.OnErrorNotImplementedException: Can't make API call urlfetch.Fetch in a thread that is neither the original request thread nor a thread created by ThreadManager
[INFO]  at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704)
[INFO]  at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701)
[INFO]  at io.reactivex.internal.observers.LambdaObserver.onError(LambdaObserver.java:74)
[INFO]  at io.reactivex.internal.observers.LambdaObserver.onNext(LambdaObserver.java:64)
[INFO]  at io.reactivex.internal.operators.observable.ObservableInterval$IntervalObserver.run(ObservableInterval.java:83)
[INFO]  at io.reactivex.internal.schedulers.ScheduledDirectPeriodicTask.run(ScheduledDirectPeriodicTask.java:39)
[INFO]  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[INFO]  at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
[INFO]  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access1(ScheduledThreadPoolExecutor.java:180)
[INFO]  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
[INFO]  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
[INFO]  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
[INFO]  at java.lang.Thread.run(Thread.java:748)
[INFO] Caused by: 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
[INFO]  at com.google.apphosting.api.ApiProxy$CallNotFoundException.foreignThread(ApiProxy.java:844)
[INFO]  at com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:116)
[INFO]  at com.google.appengine.api.urlfetch.URLFetchServiceImpl.fetch(URLFetchServiceImpl.java:40)
[INFO]  at com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection.fetchResponse(URLFetchServiceStreamHandler.java:543)
[INFO]  at com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection.getInputStream(URLFetchServiceStreamHandler.java:422)
[INFO]  at com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection.getResponseCode(URLFetchServiceStreamHandler.java:275)
[INFO]  at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:84)
[INFO]  at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
[INFO]  at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
[INFO]  at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:99)
[INFO]  at org.springframework.social.oauth1.OAuth1RequestInterceptor.intercept(OAuth1RequestInterceptor.java:48)
[INFO]  at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:86)
[INFO]  at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:70)
[INFO]  at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
[INFO]  at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
[INFO]  at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:652)
[INFO]  at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:628)
[INFO]  at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:303)
[INFO]  at org.springframework.social.twitter.api.impl.UserTemplate.getUserProfile(UserTemplate.java:60)
[INFO]  at tbetous.SubscribeService$test.accept(SubscribeService.kt:20)
[INFO]  at tbetous.SubscribeService$test.accept(SubscribeService.kt:11)
[INFO]  at io.reactivex.internal.observers.LambdaObserver.onNext(LambdaObserver.java:60)
[INFO]  ... 9 more

我很确定它与 google 应用引擎有关。当我 运行 我的应用程序时,我使用 mvn appengine:devserver。谁能帮帮我?

我找到了我的解决方案。多亏了这个link。 GAE 不适用于 RxJava,因为它不遵守 Google 标准环境的限制。我必须指定 RxJava 如何创建线程。

这是我的代码:

val scheduler : Scheduler = Schedulers.from(ScheduledThreadPoolExecutor(3, ThreadManager.backgroundThreadFactory()))
RxJavaPlugins.setComputationSchedulerHandler { scheduler }

之后我就可以使用 RxJava 了:

subscriber = Observable.interval(1, TimeUnit.SECONDS)
                    .map { twitter.userOperations().getUserProfile("azeazeaz").followersCount }
                    .subscribe {it -> println(it)}