谷歌应用引擎和Rx-Java?

5
2个回答

6
你应该创建 RxJavaSchedulersHook 的子类并重写它的方法,使用你自己的调度器,该调度器使用 com.google.appengine.api.ThreadManager。我是这样做的:
public class MyThreadSchedulersHook extends RxJavaSchedulersHook {

private final Executor executor = new ScheduledThreadPoolExecutor(10, ThreadManager.backgroundThreadFactory());

@Override
public Scheduler getComputationScheduler() {
    return Schedulers.from(executor);
}

@Override
public Scheduler getIOScheduler() {
    return Schedulers.from(executor);
}

@Override
public Scheduler getNewThreadScheduler() {
    return Schedulers.from(executor);
}
}

接下来你需要注册这个钩子。最好在ServletContextListener实现中完成:

public class ContextListener implements ServletContextListener {

@Override
public void contextInitialized(final ServletContextEvent servletContextEvent) {
    RxJavaPlugins.getInstance().registerSchedulersHook(new RxMainThreadSchedulersHook());
}

@Override
public void contextDestroyed(final ServletContextEvent servletContextEvent) {
    // App Engine does not currently invoke this method.
}
}

对我来说有效。


这个对你仍然有效吗?我仍然遇到了权限被拒绝的安全异常。我的钩子在安全异常之前已经注册了。我假设MyThreadSchedulersHookRxMainThreadSchedulersHook是同一个类,你只是在更新此帖子时将其重命名了。 - ZakTaccardi
是的,你说得对,RxMainThreadSchedulersHook和MyThreadSchedulersHook是同一个类。而且它仍然对我有用。这里有一个Github线程,我在那里描述了我的问题,然后找到了解决方案- https://github.com/ReactiveX/RxJava/issues/2918在钩子方法中调用Schedulers.from(executor)很重要,并且不要在钩子注册之前定义Schedulers类。 - Roman Savin
有趣。这在前端模块上不起作用,对吧? - Patrick Jackson
1
@user1923898 找到了我的问题——它与 Retrofit 有关,它会自动为其 RxJava 实现生成一个新线程。需要找到一种方法来覆盖该线程创建。 - ZakTaccardi
@Patrick ThreadManager.currentRequestThreadFactory() 是你想要的... - VallaDanger
现在 RxJavaPlugins.getInstance() 已经被弃用,你应该使用 RxJavaSchedulersHook / _RxJavaHooks_,例如 RxJavaSchedulersHook.createNewThreadScheduler(ThreadManager.currentRequestThreadFactory()),它将返回一个 Scheduler,你可以将其传递给 RxJavaHooks.onNewThreadScheduler(Scheduler) - VallaDanger

2
问题是Google Appengine中Java线程的限制: https://developers.google.com/appengine/docs/java/#Java_The_sandbox RxJava在 Scheduler 实现中使用 Java Thread 和 Executor。因此,一些涉及并发 Scheduler 的代码不能在 Google Java Sandbox 中运行。
如果你想在 Google Appengine 中使用 Scheduler,你需要自己实现一个特殊的 Scheduler。此外,一些操作符可能默认使用 Scheduler,例如 delay 默认使用 Schedulers.computation()。记得使用它们的 Scheduler 重载方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接