问题描述
我正在Spring Boot应用程序上本地测试POST端点。我有一个方法可以生成一个光纤线程来运行一组调用端点A的指令,我的POST端点将返回A返回的结果。但是,当我的POST请求完成时,postman中显示的结果为空。 我的代码如下
@RequestMapping("/prediction")
public CustomResponse prediction(@RequestBody CustomRequest input,HttpServletRequest request) {
return predictionClass.prediction(input);
}
public CustomResponse prediction(CustomRequest input) {
CustomResponse customResponse = new customResponse();
new Fiber<CustomResponse>(new SuspendableRunnable() {
public void run() throws SuspendExecution,InterruptedException {
List<CustomRequest> inputs = new ArrayList<>();
// A for loop is here to duplicate CustomRequest input parameter received and populate the inputs list
List<CustomResponse> customResponses = inputs.stream()
.map(req -> processPrediction(req)).collect(Collectors.toList());
for (CustomResponse x : customResponses) {
if (inputs.size() > 1) {
for (String outputKey : x.getOutputVars().keySet()) {
customResponse.getOutputVars().put(x.getModelName() + "_" + outputKey,x.getOutputVars().get(outputKey));
}
} else {
// Else statement will be run because the input is only size 1
customResponse.getOutputVars().putAll(x.getOutputVars());
}
System.out.println(customResponse.getOutputVars().size());
}
}).start();
return customResponse;
}
public CustomResponse processPrediction(CustomRequest input) {
CustomResponse res = new CustomResponse();
RestTemplate gzipRestTemplate = new RestTemplateBuilder()
.additionalInterceptors(new GzipHttpRequestInterceptor())
.build();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Map<String,Object>> entity = new HttpEntity<>(input,headers);
ResponseEntity<Map> responseEntity = gzipRestTemplate.postForEntity("an-endpoint-url",entity,Map.class);
Map<String,Object> outputs = (Map<String,Object>) responseEntity.getBody();
res.getOutputVars().putAll(outputs);
return res;
}
在此测试中,我的输入只有1号大小,当我使用Postman触发POST请求时,System.out.println(customResponse.getOutputVars().size());
返回16,但在Postman上显示我的outputVars为空。
有趣的是,我决定做如下2个实验。
实验1
public CustomResponse prediction() {
CustomResponse customResponse = new CustomResponse ();
new Fiber<Void>(new SuspendableRunnable() {
public void run() throws SuspendExecution,InterruptedException {
customResponse .setModelName("name");
Map<String,Object> test = new HashMap<>();
test.put("pcd4Score","hello");
customResponse .getOutputVars().put("message","hello");
}
}).start();
return customResponse ;
}
邮递员返回带有消息和问候的customResponse
实验2
此实验与实验1相同,但具有Thread.sleep(1000);我以为thread.sleep可以代表我的原始代码中的processPrediction
public CustomResponse prediction() {
CustomResponse customResponse = new CustomResponse ();
new Fiber<Void>(new SuspendableRunnable() {
public void run() throws SuspendExecution,"hello");
}
}).start();
return customResponse ;
}
这一次customResponse为空,并且在我的spring boot应用程序终端中,错误是
[quasar] ERROR: while transforming {the-path-to-my-class-for-prediction-method}$1: Unable to instrument {the-path-to-my-class-for-prediction-method}$1#run()V because of blocking call to java/lang/Thread#sleep(J)V
感觉实验1是成功的,因为指令不是CPU密集型的,我知道我可以用一种单独的方法启动光纤的方式进行编码,然后仅调用prediction
,因为好像邮递员返回了空的CustomResponse,然后只有run()
中的指令开始运行,我只是想了解Fiber的行为。我无法根据自己的情况进行查询(我的Google关键字是Rest端点,在启动光纤线程后未返回结果),因此我在stackoverflow上询问了此问题。我对Java主题中的整个多线程也很陌生。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)