Как изменить переменную сеанса из потока в java весенней загрузке - PullRequest
0 голосов
/ 28 мая 2020

У меня есть метод 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;
    }

Пожалуйста, помогите. Заранее спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...