Context loss when async invoke
- Dominant language
- Java
- Stars
- 41.6k
- Forks
- 26.4k
- Avg merge
- 15h 13m
- Merged PRs (30d)
- 4
Description
provider service method:
```
public CompletableFuture newToken(NewTokenInfo tReq) {
TokenInfo tokenInfo = new TokenInfo(JsonUtils.toJson(tReq), 60);
// 可以设置回应附加信息
// RpcContext.getServerResponseContext().setAttachment("testInfo", JsonUtils.toJson(tokenInfo));
// 可以设置回应附加信息
// RpcContext.getServerContext().setAttachment("testInfo", JsonUtils.toJson(tokenInfo));
CompletableFuture completableFuture = new CompletableFuture<>();
completableFuture = completableFuture.completeAsync(()->{
logger.debug("tokenInfo:" + JsonUtils.toJson(tokenInfo));
return 1;
}, Executors.newFixedThreadPool(1));
// 不可以设置回应附加信息
RpcContextAttachment serverResponseContext = RpcContext.getServerResponseContext();
// RpcContextAttachment serverResponseContext = RpcContext.getClientAttachment();
// RpcContextAttachment serverResponseContext = RpcContext.getServerContext();
// RpcServiceContext serverResponseContext = RpcContext.getServiceContext();
// RpcServiceContext serverResponseContext = RpcContext.getCurrentServiceContext();
// RpcContextAttachment serverResponseContext = RpcContext.getClientResponseContext();
// RpcContextAttachment serverResponseContext = RpcContext.getServerAttachment();
completableFuture = completableFuture.thenApply(ret->{
// 不可以设置回应附加信息
// RpcContextAttachment serverResponseContext = RpcContext.getServerResponseContext();
// RpcContextAttachment serverResponseContext = RpcContext.getClientAttachment();
// RpcContextAttachment serverResponseContext = RpcContext.getServerContext();
// RpcServiceContext serverResponseContext = RpcContext.getServiceContext();
// RpcServiceContext serverResponseContext = RpcContext.getCurrentServiceContext();
// RpcContextAttachment serverResponseContext = RpcContext.getClientResponseContext();
// RpcContextAttachment serverResponseContext = RpcContext.getServerAttachment();
serverResponseContext.setAttachment("testInfo", JsonUtils.toJson(tokenInfo));
return ret;
});
return completableFuture;
}
```
consumer :
```
NewTokenInfo tReq = new NewTokenInfo("testType", "testToken");
CompletableFuture future = tokenRpcProxy.newToken(tReq);
CompletableFuture completableFuture = future.thenAccept(ret->{
logger.debug("newToken: " + ret + ", testInfo: " + RpcContext.getClientResponseContext().getAttachment("testInfo"));
logger.debug("newToken: " + ret + ", testInfo: " + RpcContext.getServerContext().getAttachment("testInfo"));
});
try {
completableFuture.get();
} catch (Exception e) {
throw new RuntimeException("未知异常", e);
}
```
provider的方法是异步执行,异步执行完后才能往RpcContext设置回应附加信息,这种情况回应附加信息没法传递到consumer这边
Contributor guide
Research direction
Start with the provider and consumer CompletableFuture examples and trace RpcContext attachment access before and after the asynchronous callbacks. Reproduce the provider-side attachment set after async completion, then verify whether the consumer receives testInfo; done means the response attachment remains available across the asynchronous invocation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend-api-design, distributed-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100