我需要一种功能,该功能允许异步将消息推送到我的PublishSubject
并通过ConnectableObservable
以一定的速度(实际上是一个一个地)处理它们。不幸的是,似乎onNext
中对PublishSubject
的调用直到基础Subscriber
处理该消息后才释放。
处理每条消息要花好几秒钟的时间,在调试模式下,我发现它在调用将消息推送到PublishSubject的方法从堆栈中删除之前已执行-"After push..."
始终在内部日志内部之后出现在控制台中Subscriber
...
所以我有这个RestEndpoint:
@PUT
@Path("{id}")
@TokenAuthenticated
public Response postResource(@PathParam(value="id") final String extId) {
executorService.execute(new Runnable() {
@Override
public void run() {
try {
Message metadata = processor.apply(extId);
log.info("Before push...");
dataImporter.pushData(metadata);
log.info("After push...");
} catch (Exception e) {
e.printStackTrace();
}
}
});
return Response.ok("Request received successfully").build();
}
这是DataImporter的构造函数:
public DataImporter(final String configFile) {
dataToImportSubject = PublishSubject.create();
dataToImportObservable = dataToImportSubject.publish();
dataToImportObservable.connect();
dataToImportObservable
.onBackpressureBuffer(1, new Action0() {
@Override
public void call() {
logger.debug("Buffer full...");
}
})
.subscribeOn(Schedulers.io())
.subscribe(new Subscriber<Message>() {
@Override
public void onCompleted() {
// TODO Auto-generated method stub
}
@Override
public void onError(Throwable e) {
logger.error("Error importing "+e.getMessage());
}
@Override
public void onNext(Message value) {
request(1);
importResult(configFile, value);
}
@Override
public void onStart() {
request(1);
}
});
}
然后,DataImporter的pushData
只是推向PublishSubject
的{{1}}方法。.:
onNext
这是public void pushData(Message metadata) {
dataToImportSubject.onNext(metadata);
}
和PublishSubject
的声明:
ConnectableObservable
答案 0 :(得分:2)
PublishSubject
在原始onXXX
调用的线程上发出给其使用者:
计划程序:
PublishSubject
在特定的Scheduler
上默认不运行,并且Observer
会在线程中收到有关分别调用onXXX
方法的通知。
您必须使用observeOn
将处理移至其他线程,因为observeOn
可以将onXXX
调用移至另一个线程。
subscribeOn
通常不会对Subject
产生任何实际影响,因为它只会影响订阅线程,并且不会调制对这些主题的后续onXXX
调用。
答案 1 :(得分:0)
默认情况下,RxJava是同步的。您需要在观察者链中引入运算符,以对其他线程执行操作。当您阅读Observable
中每个运算符的文档时,将看到诸如“ ...在特定调度程序上没有运算符”之类的语句-这表明数据同步流过该运算符。
要使观察者链在其他线程上执行操作,可以将subscribeOn()
之类的运算符与调度程序一起使用,以对该调度程序执行操作。在您的示例中,您可能希望使用Schedulers.io()
提供后台线程。