我是Reactor的新手,我正在尝试更新现有的Spring休息服务以等待接收100条消息,或者直到上次保存之后的时间超过30秒才能保存我接收的消息。
@RequestMapping(method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void create(@RequestBody String reqJsonString) throws JsonParseException, JsonMappingException, IOException {
Flux.just(json).bufferTimeout(100, Duration.ofSeconds(30))
.publishOn(Schedulers.elastic()).subscribe(list -> {
LOG.info("size:”+list.size());
this.save(list);
});
}
但即使我向其他服务发送了数百条消息,该列表也只包含一条消息。 如何在列表中缓冲POST消息之前将它们保存在一个批处理中?
答案 0 :(得分:0)
我不确定我是否理解你想做什么,但每当你调用Flux.just(json)时,你都会创建一个新项目的Flux。
你必须创建一个发布者并为每个json调用onNext。 subscribe()部分将不会在POST处理。
这是我从文档中创建的一个简单示例(对不起我的邋))
import reactor.core.publisher.Flux;
import reactor.core.publisher.UnicastProcessor;
import java.time.Duration;
import java.util.Arrays;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Test {
private UnicastProcessor<String> hotSource = UnicastProcessor.create();
private Flux<String> hotFlux = hotSource.publish().autoConnect();
public void nextItem(String string){
hotSource.onNext(string);
}
public void complete(){
hotSource.onComplete();
}
public static void main(String[] args) throws InterruptedException {
Test test = new Test();
// simulate POST calls executed in //
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 2, 1L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(5));
threadPoolExecutor.submit(() -> {
try {
//Should get the first two before the first 2s
test.nextItem("First");
Thread.sleep(1000);
test.nextItem("Second");
Thread.sleep(1000);
//Should get a single element, since 2.5s will pass between 3rd and 4th
test.nextItem("Third");
Thread.sleep(2500);
//Should get a single element, and the complete
test.nextItem("Fourth");
Thread.sleep(3000);
test.complete();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
test.hotFlux.bufferTimeout(2, Duration.ofMillis(2000))
.subscribe(
list -> System.out.println("Got: " + Arrays.toString(list.toArray()))
);
threadPoolExecutor.awaitTermination(10L, TimeUnit.SECONDS);
threadPoolExecutor.shutdown();
}
}
答案 1 :(得分:0)
有了你的想法,为此你需要像共享Processor
那样负责接收结果的东西:
class MyController {
private Sink<String> sink;
MyController() {
Flux.<String>push(sink -> this.sink = sink)
.bufferTimeout(100, Duration.ofSeconds(30))
.publishOn(Schedulres.elastic())
.subscribe(list -> {
LOG.info("size:”+list.size());
this.save(list);
});
}
@RequestMapping(method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void create(@RequestBody String reqJsonString) throws JsonParseException, JsonMappingException, IOException {
sink.onNext(reqJsonString);
}
}
答案 2 :(得分:0)
@RequestMapping(method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void create(@RequestBody String reqJsonString) throws JsonParseException, JsonMappingException, IOException {
Flux.just(json).bufferTimeout(100, Duration.ofSeconds(30))
.publishOn(Schedulers.elastic()).subscribe(list -> {
LOG.info("size:”+list.size());
this.save(list);
});
}