У меня есть метод RequestMethod.POST под названием «doBigTask» в моем контроллере. После отправки POST этот метод вызывает внешний медленный API для получения данных. Итак, я сделал это Asyn c. После вызова POST я делаю следующее:
- Я создаю «токен taskId» и сохраняю его в переменной списка сеанса.
- Я делаю вызов метода asyn c для обработки потребление и обработка URL-адресов внешней службы.
- и, наконец, вернули будущую переменную org.springframework.util.concurrent.ListenableFuture из метода asyn c.
Таким образом, когда пользователь проверяет на странице «status» с помощью отдельного вызова get (в том же сеансе) пользователь видит, что «taskId 12345 = In Progress».
Я хочу сделать следующее:
- Прикрепите обратный вызов к переменной future с помощью ListenableFutureCallback
- В переопределенном методе onSuccess (содержащем завершенный taskId) удалите идентификатор завершенной задачи из переменной списка сеансов.
Проблема в : Поскольку onSuccess не находится в контексте запроса и принадлежит контексту потока, он не знает переменную списка сеансов. Переменная списка ion в потокобезопасном режиме в методе ListenableFutureCallback-> onSuccess "?
Вот что у меня есть:
У меня есть такой класс SessionScope:
@SessionScope
@Service
public class TasksTrackingObj implements Serializable {
private static final long serialVersionUID = -2282835305256598837L;
private final ArrayBlockingQueue<String> tasks;
public TasksTrackingServiceImpl() {
this.tasks = new ArrayBlockingQueue<String>(30);
}
public void addTask(String taskId) {
try {
this.tasks.offer(taskId, 10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
}
}
public String removeTask(String taskId) {
try {
return this.tasks.poll(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
}
return null;
}
public boolean contains(String taskId) {
return this.tasks.contains(taskId);
}
@Override
public ArrayBlockingQueue<String> getTasks() {
return tasks;
}
}
В моем классе контроллера я выполнил autowire для своего класса области сеанса:
@Autowired
private TasksTrackingObj taskTrackingService;
Мой метод запроса POST выглядит так:
@RequestMapping(value = "/bigtask", params = { "bigtask" }, method = RequestMethod.POST)
public ModelAndView doBigTask() throws InterruptedException, ExecutionException {
String tokenId = Util.getGUID();
this.taskTrackingService.addTask(tokenId);
ListenableFuture<String> future = this.bigTaskHandler.handleTheBigOperation(tokenId);
future.addCallback(new ListenableFutureCallback<String>() {
@Override
public void onSuccess(String completedTokenId) {
final Logger logger0 = LoggerFactory.getLogger(HomeController.class);
logger0.info("Task completed notification: "+completedTokenId);
taskTrackingService.getTasks().remove(completedTokenId); // this is not working
}
@Override
public void onFailure(Throwable arg0) {
final Logger logger0 = LoggerFactory.getLogger(HomeController.class);
logger0.error(arg0.getMessage());
}
});
ModelAndView mv = new ModelAndView();
mv.setViewName("home");
mv.addObject("bigoperationresult", "your task is in progress: "+taskId );
return mv;
}
Затем метод GET для проверка статуса отложенных задач выглядит так:
@RequestMapping(value = "/bigtask", method = RequestMethod.GET)
public ModelAndView getBigTaskResult() {
ModelAndView mv = new ModelAndView();
mv.setViewName("home");
mv.addObject("bigoperationresult", "your In progress tasks are: "+this.taskTrackingService.toString());
return mv;
}
Пожалуйста, помогите. Заранее спасибо.