我首先在项目中使用webflux,只是想在长时间处理的情况下设置超时时间。
@GetMapping("/{id}")
private Mono<ResponseEntity<String>> getEmployeeById(@PathVariable
String id) {
return Mono.just(id).map(updateTweet -> {
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new ResponseEntity<>(updateTweet, HttpStatus.OK);
}).timeout(Duration.ofSeconds(3)).onErrorReturn(new ResponseEntity<>("0000", HttpStatus.OK));
}
期望:3秒钟后,此函数将返回。 实际结果:10秒钟后,此函数返回。
答案 0 :(得分:1)
TimeUnit.SECONDS.sleep(10)
的作用是调用Thread.sleep()
。这把当前
进入睡眠模式10秒钟。
由于您是在map
内执行此操作,因此进入睡眠状态的线程是当前线程。等待timeOut
的代码也位于当前线程上,因此直到sleep
超时后才生效。因此,在进行反应式编程时,应避免执行任何与Thread
相关的操作。
如果要在上述代码中模拟长时间运行的过程,则可以调用受您控制的外部API,该API在发送响应之前等待3秒以上,或者使用delay*
运算符之一。
答案 1 :(得分:0)
在您的代码中,.map
和.timeout
都在订阅线程中。 .sleep(10)
导致当前正在执行的线程进入10s
的睡眠状态(暂时停止执行)。因此,3s
超时后,线程将无法执行。
您应该使用 publishOn 将.map
移至调度程序线程。
@GetMapping("/{id}")
private Mono<ResponseEntity<String>> getEmployeeById(@PathVariable
String id) {
Scheduler singleThread = Schedulers.single();
return Mono.just(id).publishOn(singleThread).map(updateTweet -> {
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new ResponseEntity<>(updateTweet, HttpStatus.OK);
}).timeout(Duration.ofSeconds(3)).onErrorReturn(new ResponseEntity<>("0000", HttpStatus.OK));
}