gpt4 book ai didi

resteasy - 关闭异步 resteasy 客户端调用的最佳方法

转载 作者:行者123 更新时间:2023-12-03 17:26:42 37 4
gpt4 key购买 nike

我有以下代码:

var threadsWaiter = new CountDownLatch(customers.size());
for(var c: List<Customer> customers) {
sendSms(c.phoneNr, threadsWaiter)
}
threadsWaiter.await();

public void sendSms(String phoneNr, CountDownLatch threadsWaiter) {
ResteasyClientBuilder.newClient()
.target(smsUrl)
.queryParam("to", phoneNr)
.queryParam("message", message)
.request()
.async()
.get(new InvocationCallback<String>() {
@Override
public void completed(String res) {
threadsWaiter.countDown();
if (res != null && !res.contains("code=ok") {
logger.error("Received sms response for '{}'\n{}", phoneNr, res);
} else {
logger.debug("Sms sent to '{}'", phoneNr);
}
}

@Override
public void failed(Throwable throwable) {
threadsWaiter.countDown();
logger.error("Error sending sms for {}: \n{}", phoneNr, throwable.getMessage());
}
});
}
我从控制台收到以下警告:

RESTEASY004687: Closing a class org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine instance for you. Please close clients yourself.


关闭此客户端调用的正确方法是什么?因为这可能是应用程序中潜在内存泄漏的来源。甚至我从 RestEasy 收到了这个警告,它会自动为我关闭客户端,但我有一种强烈的感觉,它不会关闭所有客户端,因为我看到指标中的内存大幅增加,这不会“去下来”一段时间后。
我已经在 try-finally 之间放置了其余的客户端调用,但问题在于您可以在调用完成之前关闭客户端。可以在 completed(..)中关闭客户端吗?和 failed(..) InvocationCallback 中的方法还是有更好的方法?

最佳答案

使用 Quarkus 执行此操作的最佳方法是使用 REST client with async support . 示例:

    /**
* This is the client stub.
*/
@Path("/sms/response") // base URL is set in application.yml
@RegisterRestClient
public interface SmsServiceClient {

@GET
@Produces(MediaType.TEXT_PLAIN)
CompletionStage<String> sendSms(
@QueryParam("to") String phoneNr,
@QueryParam("message") String message);
}
在下面的例子中,我使用 SmallRye Mutiny转换 CompletionStageUni它有一个更精简的 API。但是您可以使用 CompletionStage 实现相同的效果。 .通常,我不会用 CountDownLatch.await() 阻止执行方法。我把它放在那里以保持代码与您的示例相似。
    /**
* This class will actually use the client.
*/
@Slf4J
@ApplicationScoped
public class MySomething {

@Inject
@RestClient
SmsServiceClient smsClient;

public void sendSmsInLoop() {
var waiter = new CountDownLatch(customers.size());
customers.forEach(customer -> {
Uni.createFrom().completionStage(
smsClient.sendSms(customer.getPhoneNr(), "Lorem Ipsum...")
).onItem().invoke(responseString -> {
if (responseString == null || !responseString.contains("code=ok")) {
log.error("Unexpected sms response for '{}'\n{}", customer.getPhoneNr(), responseString);
} else {
log.debug("Sms sent to '{}'", customer.getPhoneNr());
}
}).onFailure().invoke(throwable -> {
log.error("Error sending sms to '{}'\n{}", customer.getPhoneNr(), throwable.getMessage());
}).eventually(() -> waiter.countDown());
});
waiter.await();
}
}

关于resteasy - 关闭异步 resteasy 客户端调用的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59957599/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com