如果得到回复,如何等待30秒或完成?

时间:2023-01-26 09:25:44

I have a method below which sends out a notification and then waits 30 seconds. But what I am trying to achieve is that send out a notification then keep checking the database every second (too much?) to see if I got a response from the notification. If I got a response from the notification then I don't need to wait any longer and I need to continue. Otherwise I need to wait until 30 seconds.

我有一个方法,下面发出通知,然后等待30秒。但我想要实现的是发送通知,然后每秒检查数据库(太多?),看看我是否得到了通知的响应。如果我收到通知的回复,那么我不需要再等了,我需要继续。否则我需要等到30秒。

@RequestMapping("/sendNotification")
public HashMap<String, Object> sendNotification(@RequestBody SingleFieldPojo singleFieldPojo) {
    MessagingFCM.sendMessageToDevice("Title", singleFieldPojo.getToken());
    final CountDownLatch latch = new CountDownLatch(1);        
    try {
        latch.await(30, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
        e.printStackTrace();
        latch.countDown();
    }
    latch.countDown();
    HashMap<String, Object> output = new HashMap<>();
    output.put("success", jobStatusRepo.findById(singleFieldPojo.getJobBoardId()));
    return output;
}

2 个解决方案

#1


3  

You can do this using a CompletableFuture.

您可以使用CompletableFuture执行此操作。

try {
    thing = CompletableFuture.runAsync(myTask).get(10, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException e) {
    throw new RuntimeException(e); 
} catch (TimeoutException | CancellationException e) {
    // it timed out or was cancelled
}

This way however will stop the task if the timeout is reached. I'm not sure if that's what you want.

但是,如果达到超时,这种方式将停止任务。我不确定这是不是你想要的。

#2


0  

@RequestMapping("/sendNotification")
    public HashMap<String, Object> sendNotification(@RequestBody SingleFieldPojo singleFieldPojo) {
        System.out.println("category: " + singleFieldPojo);

        if (!StringUtils.isEmpty(singleFieldPojo.getBrowserIdToken())) {
            MessagingFCM.sendMessageToDevice("Title", singleFieldPojo.getJobBoardId(), singleFieldPojo.getBrowserIdToken());
        }
        if (!StringUtils.isEmpty(singleFieldPojo.getPhoneIdToken())) {
            MessagingFCM.sendMessageToDevice("Title", singleFieldPojo.getJobBoardId(), singleFieldPojo.getPhoneIdToken());
        }

        // Run a task specified by a Supplier object asynchronously
        CompletableFuture<HashMap<String, Object>> future = CompletableFuture.supplyAsync(() -> {
            Optional<JobStatus> jobStatus = jobStatusRepo.findById(singleFieldPojo.getJobBoardId());
            HashMap<String, Object> output = new HashMap<>();
            if (jobStatus.isPresent()) {
                String status = jobStatus.get().getJobStatus();
                final CountDownLatch latch = new CountDownLatch(1);
                try {
                    do {
                        Optional<JobStatus> jobStatusNew = jobStatusRepo.findById(singleFieldPojo.getJobBoardId());
                        if(jobStatusNew.isPresent()) {
                            if(StringUtils.equals(status, "accept")) {
                                latch.countDown();
                            }
                        }
                        status = jobStatusNew.get().getJobStatus();
                        latch.await(2, TimeUnit.SECONDS);
                    } while (status.equals("accepted"));

                } catch (InterruptedException e) {
                    throw new IllegalStateException(e);
                }
            }
            return output;
        });

        // Block and get the result of the Future
        HashMap<String, Object> result = null;
        try {
            result = future.get(30, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }
        HashMap<String, Object> output = new HashMap<>();
        output.put("success", jobStatusRepo.findById(singleFieldPojo.getJobBoardId()));
        return output;
    }

#1


3  

You can do this using a CompletableFuture.

您可以使用CompletableFuture执行此操作。

try {
    thing = CompletableFuture.runAsync(myTask).get(10, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException e) {
    throw new RuntimeException(e); 
} catch (TimeoutException | CancellationException e) {
    // it timed out or was cancelled
}

This way however will stop the task if the timeout is reached. I'm not sure if that's what you want.

但是,如果达到超时,这种方式将停止任务。我不确定这是不是你想要的。

#2


0  

@RequestMapping("/sendNotification")
    public HashMap<String, Object> sendNotification(@RequestBody SingleFieldPojo singleFieldPojo) {
        System.out.println("category: " + singleFieldPojo);

        if (!StringUtils.isEmpty(singleFieldPojo.getBrowserIdToken())) {
            MessagingFCM.sendMessageToDevice("Title", singleFieldPojo.getJobBoardId(), singleFieldPojo.getBrowserIdToken());
        }
        if (!StringUtils.isEmpty(singleFieldPojo.getPhoneIdToken())) {
            MessagingFCM.sendMessageToDevice("Title", singleFieldPojo.getJobBoardId(), singleFieldPojo.getPhoneIdToken());
        }

        // Run a task specified by a Supplier object asynchronously
        CompletableFuture<HashMap<String, Object>> future = CompletableFuture.supplyAsync(() -> {
            Optional<JobStatus> jobStatus = jobStatusRepo.findById(singleFieldPojo.getJobBoardId());
            HashMap<String, Object> output = new HashMap<>();
            if (jobStatus.isPresent()) {
                String status = jobStatus.get().getJobStatus();
                final CountDownLatch latch = new CountDownLatch(1);
                try {
                    do {
                        Optional<JobStatus> jobStatusNew = jobStatusRepo.findById(singleFieldPojo.getJobBoardId());
                        if(jobStatusNew.isPresent()) {
                            if(StringUtils.equals(status, "accept")) {
                                latch.countDown();
                            }
                        }
                        status = jobStatusNew.get().getJobStatus();
                        latch.await(2, TimeUnit.SECONDS);
                    } while (status.equals("accepted"));

                } catch (InterruptedException e) {
                    throw new IllegalStateException(e);
                }
            }
            return output;
        });

        // Block and get the result of the Future
        HashMap<String, Object> result = null;
        try {
            result = future.get(30, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }
        HashMap<String, Object> output = new HashMap<>();
        output.put("success", jobStatusRepo.findById(singleFieldPojo.getJobBoardId()));
        return output;
    }