线程启动后,类星体光纤返回空结果

问题描述

我正在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 (将#修改为@)