Spring boot 线程启动后返回空结果的quasar光纤
我正在spring boot应用程序上本地测试POST端点。我有一个方法生成一个光纤线程来运行一组指令,这些指令调用端点a,我的POST端点返回a返回的结果。但是,当我的POST请求完成时,postman中显示的结果为空。 我的代码如下Spring boot 线程启动后返回空结果的quasar光纤,spring-boot,rest,api-gateway,quasar,fibers,Spring Boot,Rest,Api Gateway,Quasar,Fibers,我正在spring boot应用程序上本地测试POST端点。我有一个方法生成一个光纤线程来运行一组指令,这些指令调用端点a,我的POST端点返回a返回的结果。但是,当我的POST请求完成时,postman中显示的结果为空。 我的代码如下 @RequestMapping("/prediction") public CustomResponse prediction(@RequestBody CustomRequest input, HttpServletRequest
@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;
}
邮递员返回customResponse,其中包含消息和hello
实验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, InterruptedException {
customResponse .setModelName("name");
Map<String, Object> test = new HashMap<>();
test.put("pcd4Score", "hello");
customResponse .getOutputVars().put("message", "hello");
}
}).start();
return customResponse ;
}
公共客户响应预测(){
CustomResponse CustomResponse=新的CustomResponse();
新光纤(新的SuspendableRunnable(){
public void run()抛出SuspendExecution,InterruptedException{
customResponse.setModelName(“名称”);
Map test=newhashmap();
测试。放置(“pcd4Score”,“hello”);
customResponse.getOutputVars().put(“message”、“hello”);
}
}).start();
返回客户响应;
}
这次customResponse是空的,在我的spring boot应用程序终端中,错误是
[quasar]错误:在转换{预测方法的我的类的路径}$1时:无法插入{预测方法的我的类的路径}$1#run()V,因为阻止了对java/lang/Thread的调用#sleep(J)V
感觉实验1是成功的,因为指令不是cpu密集型的,我知道我可以用另一种方法启动光纤,然后只调用
prediction
,因为邮递员似乎返回空的CustomResponse,然后只有run()
中的指令开始运行,我只是想了解纤维的行为。我很难用谷歌搜索我的情况(我的谷歌关键词是rest端点,在光纤线程启动后不会返回结果),因此我在stackoverflow上问这个问题。我对java中的整个多线程主题也很陌生。在像这样返回customResponse
之前,我通过添加光纤连接解决了这个问题。然而,仅仅为.join()进行一次尝试并捕获似乎不是很优雅,有没有更优雅的方法来重做整个方法
public CustomResponse prediction(CustomRequest input) {
CustomResponse customResponse = new customResponse();
Fiber fiber = 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();
try {
fiber.join();
} catch (Exception e) {
e.printStackTrace();
}
return customResponse;
}
公共CustomResponse预测(CustomRequest输入){
CustomResponse CustomResponse=新的CustomResponse();
光纤=新光纤(新的SuspendableRunnable(){
public void run()抛出SuspendExecution,InterruptedException{
列表输入=新的ArrayList();
//此处的for循环用于复制接收到的CustomRequest输入参数并填充输入列表
List customResponses=inputs.stream()
.map(req->processPrediction(req)).collect(Collectors.toList());
对于(CustomResponse x:customResponses){
if(inputs.size()>1){
for(字符串outputKey:x.getOutputVars().keySet()){
customResponse.getOutputVars().put(x.getModelName()+“”+outputKey,x.getOutputVars().get(outputKey));
}
}否则{
//Else语句将运行,因为输入的大小仅为1
customResponse.getOutputVars().putAll(x.getOutputVars());
}
System.out.println(customResponse.getOutputVars().size());
}
}).start();
试一试{
fiber.join();
}捕获(例外e){
e、 printStackTrace();
}
返回客户响应;
}
public CustomResponse prediction(CustomRequest input) {
CustomResponse customResponse = new customResponse();
Fiber fiber = 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();
try {
fiber.join();
} catch (Exception e) {
e.printStackTrace();
}
return customResponse;
}