英文:
block()/blocking() not supported in thread reactor
问题
以下是代码部分的中文翻译:
这是从API获取一些信息的逻辑:
class OneClient {
public Mono<Information> getSomeInformation(ClientRequest req) {
return getWebTarget(req)
.request(MediaType.APPLICATION_JSON_TYPE)
.headers(getHeaders(req))
.rx(MonoRxInvoker.class)
.get()
.map(this::processResponse)
.doOnError(this::processError);
}
}
这就是我们的框架如何在将请求放在不同线程的同时保持主线程不阻塞。
但是我遇到了一个问题。 getHeaders()
获取的信息如下:
public MultiValuedMap<String, Object> getHeaders() {
if(token == null) {
getTokenFromExternalApi() // 就像前面的片段一样
.map(resp -> setToken(resp))
.block();
}
return headers; // 令牌和其他静态数据
}
由于我必须在bean中存储令牌,我使用了 .block()
,但然后我遇到了异常:block()/blockFirst()/blockLast() 在线程 reactor-http-nio-5 中不受支持
。我理解为什么会出现这个错误。在非阻塞线程中进行阻塞是不被支持的。
但是,你可以建议我设计 getHeader()
的正确方式吗?谢谢。
英文:
Here is a logic to fetch some information from an API:
class OneClient {
public Mono<Information> getSomeInformation(ClientRequest req) {
return getWebTarget(req)
.request(MediaType.APPLICATION_JSON_TYPE)
.headers(getHeaders(req))
.rx(MonoRxInvoker.class)
.get()
.map(this::processResponse)
.doOnError(this::processError);
}
}
Thats how our framework is to be used by putting the request on a different thread while keeping main thread unblocked.
But I have a problem. getHeaders()
gets information like below:
public MultiValuedMap<String,Object> getHeaders() {
if(token == null) {
getTokenFromExternalApi() // just like previous snippet
.map(resp -> setToken(resp))
.block();
}
return headers; // tokens and other static data
}
Since I have to store token in the bean, I was doing .block()
, but then I get exception: block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-5
. And I understand why this error is being thrown. Blocking is unexpected in a non-blocking thread.
But
Can you suggest me the right way to design getHeader()
? Thank you.
答案1
得分: 0
抱歉,我的早期回答未完全解决您的问题。
您可以修改getHeaders()
方法以返回一个Mono
,当令牌可用时,它会发出头部对象。然后,您可以使用map()
操作符将这个Mono
与设置头部并继续执行请求的操作链接在一起。
public Mono<MultiValuedMap<String, Object>> getHeaders() {
if (token == null) {
return getTokenFromExternalApi()
.map(resp -> setToken(resp))
.then(Mono.just(headers)); // 在设置令牌后返回头部
}
return Mono.just(headers); // 如果令牌已经设置,返回头部
}
要使用这个实现,您可以按照以下方式修改webTarget
的代码:
getHeaders()
.map(headers -> {
webTarget.headers(headers);
return webTarget;
})
.flatMap(webTarget -> webTarget.rx(MonoRxInvoker.class).get())
.map(this::processResponse)
.doOnError(this::processError);
英文:
I apologize for my earlier response not fully addressing your issue.
you can modify getHeaders() to return a Mono that emits the headers object when the token is available. You can then chain this Mono with the map() operator to set the headers and continue with the request execution.
public Mono<MultiValuedMap<String,Object>> getHeaders() {
if(token == null) {
return getTokenFromExternalApi()
.map(resp -> setToken(resp))
.then(Mono.just(headers)); // return headers after setting token
}
return Mono.just(headers); // return headers if token is already set
}
To use this implementation, you can modify the webTarget code as follows:
getHeaders()
.map(headers -> {
webTarget.headers(headers);
return webTarget;
})
.flatMap(webTarget -> webTarget.rx(MonoRxInvoker.class).get())
.map(this::processResponse)
.doOnError(this::processError);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论