Как лучше всего создать очередь для длительных заданий в приложении Grails?

У меня есть приложение Grails с некоторыми оптимизациями, требующими значительных вычислительных ресурсов, со временем выполнения ~ 5 минут (возможно, больше). В настоящее время я делаю это в основном потоке запросов, т.е. для возврата запроса требуется 5 минут. Это работает, но, конечно, ужасно с точки зрения удобства использования.

Итак, как лучше всего реализовать это асинхронно? Я предполагаю, что должен быть задействован ThreadPoolExecutor, но как мне запустить и получить к нему доступ? Могу ли я смоделировать его как службу Grails? Или задание (кажется, что они предназначены только для повторяющихся заданий)?

Кроме того, как лучше всего обрабатывать статус работы? Через флаг или, возможно, целый новый класс в БД? Браузер показывает счетчик и продолжает опрос, пока статус не изменится?


person Michael Borgwardt    schedule 26.07.2009    source источник


Ответы (6)


Существует подключаемый модуль Grails background-thread, который может быть именно тем, что вам нужно.

Конечно, можно было бы создать собственный пул потоков или использовать существующий материал Java.

person Sean A.O. Harney    schedule 26.07.2009

Я бы использовал для этого grails JMS Plugin.

Затем вы можете создать службу с методом onMessage, который автоматически взаимодействует с базовым поставщиком jms (например, OpenMQ или ActiveMQ.

Это делает такие вещи довольно легкими.

person Ted Naleid    schedule 26.07.2009
comment
В чем преимущество по сравнению с простым использованием ThreadPoolExecutor? Звучит намного сложнее. - person Michael Borgwardt; 26.07.2009
comment
Это определенно сложнее. Основные преимущества заключаются в некоторых возможностях мониторинга и опроса, которые в вашем вопросе упоминаются в отношении некоторых требований. Многие подобные вещи решаются в мире JMS, но вокруг этого больше настройки/обслуживания. Это действительно зависит от того, насколько предприимчивы ваши требования. Если вас не волнует мониторинг или то, что произойдет, если ваш контейнер выйдет из строя во время его обработки, я бы сделал что-то более простое. Всего один возможный вариант. - person Ted Naleid; 26.07.2009
comment
Ах я вижу. Ну, единственный мониторинг, который мне нужен, - это пользователь, ожидающий завершения определенной работы. Мне также не нужна безопасность транзакций, поэтому я выберу более простой подход. - person Michael Borgwardt; 27.07.2009

Плагин фонового потока устарел, поэтому я бы не рекомендовал его использовать, а также JMS кажется излишним для фоновой обработки. JMS — это скорее очередь сообщений, а не утилита фоновой обработки.

Я бы порекомендовал либо использовать плагин Quartz, либо использовать gpars.

person Ganesh Krishnan    schedule 05.09.2011

В духе «самой простой вещи, которая могла бы работать», я сделал что-то подобное в качестве простого сервиса. (Конечно, это может быть слишком просто, критика приветствуется).

Я использовал функцию Groovy, заключающуюся в том, что Thread имеет статический метод запуска, который принимает закрытие. См. http://groovy.codehaus.org/groovy-jdk/java/lang/Thread.html

Я реализовал метод на сервисе, который выглядел так:

synchronized def runThreadedTask() {
  if(taskRunning) { 
    // taskRunning is defined as a service level flag to monitor job status
    // if we are already running the task just return
    return;
  }

  Thread.start {
    taskRunning = true
    // do job processing here
    taskRunning = false
  }
}
person Alex Stoddard    schedule 03.08.2009

фоновый поток установки плагина Grails

def backgroundService

backgroundService.execute("делаю свое дело", {

// работаем здесь

});

person user57660    schedule 20.08.2009

Прошло некоторое время с тех пор, как об этом спрашивали, но, поскольку он только что появился в поиске, я решил добавить, что теперь в объекте Thread есть замыкание потоков Groovy. Вы просто используете:

Thread.start {
    // async code goes here
}

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

person Bill K    schedule 15.11.2012