Google Appengine и rx-Java?

Совместима ли библиотека rxJava с Google Appengine? Если да, то есть ли ограничения? Единственная информация, которую я нашел, это упоминание о «частичной поддержке» в grepcode. http://grepcode.com/snapshot/repo1.maven.org/maven2/com.netflix.rxjava/rxjava-core/0.9.0

Что не поддерживается?


person Patrick    schedule 16.05.2014    source источник


Ответы (2)


Проблема заключается в ограничении потоков Java в Google Appengine: https://developers.google.com/appengine/docs/java/#Java_The_sandbox

RxJava использует Java Thread и Executor в реализациях Scheduler. Таким образом, коды, в которые вовлечены некоторые параллельные Scheduler, не могут работать в песочнице Google Java.

Если вы хотите использовать Scheduler в Google Appengine, вам нужно самостоятельно реализовать специальный Scheduler. Кроме того, некоторые операторы могут использовать Scheduler по умолчанию, например, delay по умолчанию использует Schedulers.computation(). Не забудьте использовать их Scheduler методы перегрузки.

person zsxwing    schedule 18.05.2014

Вы должны создать дочерний элемент 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.
}
}

Меня устраивает.

person Roman Savin    schedule 27.04.2015
comment
Это все еще работает для вас? Я все еще получаю исключение безопасности «Отказано в доступе». Мой хук регистрируется до исключения безопасности. Я предполагаю, что MyThreadSchedulersHook и RxMainThreadSchedulersHook — это один и тот же класс, который вы только что переименовали между обновлением этого поста. - person ZakTaccardi; 15.06.2015
comment
Да, вы правы, RxMainThreadSchedulersHook и MyThreadSchedulersHook — это одни и те же классы. И это все еще работает для меня. На гитхабе есть ветка, где я описал свою проблему, а потом нашел решение — github.com/ReactiveX /RxJava/issues/2918 Важно вызывать Schedulers.from(executor) в методах хука и не определять класс Schedulers до регистрации хука. - person Roman Savin; 17.06.2015
comment
Интересный. Это не работает на интерфейсных модулях, верно? - person Patrick; 19.06.2015
comment
@ user1923898 нашел мою проблему - это было с Retrofit, который автоматически создает новый поток для своей реализации RxJava. Нужно найти способ переопределить создание этого потока. - person ZakTaccardi; 22.06.2015
comment
@Patrick ThreadManager.currentRequestThreadFactory() - это то, что вам нужно... - person VallaDanger; 03.08.2016
comment
в настоящее время RxJavaPlugins.getInstance() устарел, и вы должны использовать RxJavaSchedulersHook / RxJavaHooks, например. RxJavaSchedulersHook.createNewThreadScheduler(ThreadManager.currentRequestThreadFactory()), который вернет Scheduler, который вы передадите RxJavaHooks. onNewThreadScheduler(Scheduler) - person VallaDanger; 03.08.2016