block()/blocking() 在线程反应器中不受支持。

huangapple go评论72阅读模式
英文:

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&lt;Information&gt; 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&lt;String,Object&gt; getHeaders() {
    if(token == null) {
        getTokenFromExternalApi() // just like previous snippet
        .map(resp -&gt; 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&lt;MultiValuedMap&lt;String,Object&gt;&gt; getHeaders() {
   if(token == null) {
    return getTokenFromExternalApi()
        .map(resp -&gt; 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 -&gt; {
    webTarget.headers(headers);
    return webTarget;
})
.flatMap(webTarget -&gt; webTarget.rx(MonoRxInvoker.class).get())
.map(this::processResponse)
.doOnError(this::processError);

huangapple
  • 本文由 发表于 2023年2月27日 14:33:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/75577373.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定