Запуск долгих экспериментов из веб-интерфейса - PullRequest
1 голос
/ 22 октября 2010

Я создаю исследовательское веб-приложение, которое выполняет длинный пакетный анализ, который может длиться часами.Я использую Grails , но я думаю, что это общая проблема дизайна.Пакетный процесс может быть запущен с помощью URL-адреса, например,

http://mydomain/experiment/run?a_lot_of_params

. И эта страница возвращает информацию об эксперименте (данные которого хранятся в бэкэнде и доступны через другой веб-интерфейс).).например,

Experiment finished: results available at 
http://mydomain/experiment/data/myexperiment.xml

Проблема с этим подходом заключается в следующем: если эксперимент длится несколько минут, можно оставить веб-страницу в ожидании.Но что произойдет, если эксперимент длится 10 часов?Что делать, если пользователь закрывает страницу?Есть ли правильный шаблон проектирования, которому нужно следовать для ситуаций такого типа?

Спасибо за любые подсказки.

Ответы [ 2 ]

2 голосов
/ 22 октября 2010

Вы можете дать пользователю токен и заставить его ввести этот токен для просмотра статуса процесса.

В конце процесса вы можете уведомить пользователя по электронной почте / звонить / смс.

0 голосов
/ 22 октября 2010

Является ли пакетный процесс асинхронным?Если нет, вам нужно будет запустить его в другом потоке.Пример:

class BatchController {

    def batchExecutionService // has the logic to run the batch operation

    // this should probably only take POST requests, but that's left as a later exercise
    def execute = {

        def batchId

        new Thread(new Runnable() {
            batchExecutionService.executeBatch(batchId, params)
        }).start()

        render batchId // could also set response status to 202 Accepted
    }

    def check = {
        render batchExecutionService.getStatus(params.batchId)
    }

    def retrieve = {
        if(batchExecutionService.getStatus() != Status.FINISHED) {
            // error response, could be 404 if report is not created yet, or something else
        }
        render batchExecutionService.getReport(params.batchId)
    }
}

Вышеприведенная реализация довольно грубая, но передает общее сообщение.Несколько замечаний по этому поводу:

  • Возможно, вы не захотите просто обновить Thread и использовать его, есть лучшие способы сделать это (но приведете более сложный пример),Возможным решением будет плагин BackgroundThread или плагин Quartz .
  • Возможно, действие execute не должно принимать запросы GET с параметрами запроса, как выв настоящее время делает.Но это совершенно другое обсуждение.См. this для справки.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...