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;
}