2015-05-11 2 views
1

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

Вот мой сценарий. В настоящее время мы имеем часть нашего кода, завернутую в блок Thread.start {}. Он делает это, чтобы он мог отправлять сообщения в очередь сообщений в фоновом режиме, а не блокировать запрос пользователя. Проблема, с которой мы недавно столкнулись, заключается в том, что для больших блоков работы пользователи могут выполнить другое действие, которое приведет к повторному выполнению этого блока. Поскольку он имеет резьбу, вторая передача сообщений может быть отправлена ​​до первого появления поврежденных данных.

Я хотел бы изменить этот процесс, чтобы работать как поток очереди с gpars. Я видел примеры создания пулов, таких как

def pool = GParsPool.createPool() 

или

def pool = new ForkJoinPool() 

, а затем, используя бассейн,

GParsPool.withExistingPool(pool) { 
    ... 
} 

Это похоже было бы объяснить в том случае, если пользователь снова выполняет действие, я могу повторно использовать созданный пул, и действия не будут выполняться не в порядке, если у меня есть размер пула.

Мой вопрос в том, что это лучший способ сделать это с помощью gpars? И, кроме того, как я узнаю, когда пул завершил всю свою работу? Прерывается ли это, когда все работы завершены? Если да, существует ли метод, который можно использовать для проверки завершения или завершения пула, чтобы узнать, что мне нужен новый?

Любая помощь будет оценена по достоинству.

ответ

0

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

  • Работа сгруппированных по некоторым контексте
  • заказана работа в данном контексте
  • Работа в данном контексте является синхронным
  • Дополнительные работы для контекста следует выполнять после предыдущей работы
  • Работа не должна блокировать запрос пользователя
  • контекстов являются асинхронными друг с другим
  • После работы в контексте завершения, контекст должен убирать за собой

Учитывая вышесказанное, мы реализовали следующие:

class AsyncService { 
    def queueContexts 


    def AsyncService() { 
     queueContexts = new QueueContexts() 
    } 

    def queue(contextString, closure) { 
     queueContexts.retrieveContextWithWork(contextString, true).send(closure) 
    } 

    class QueueContexts { 
     def contextMap = [:] 

     def synchronized retrieveContextWithWork(contextString, incrementWork) { 
      def context = contextMap[contextString] 

      if (context) { 
       if (!context.hasWork(incrementWork)) { 
        contextMap.remove(contextString) 
        context.terminate() 
       } 
      } else { 
       def queueContexts = this 
       contextMap[contextString] = new QueueContext({-> 
        queueContexts.retrieveContextWithWork(contextString, false) 
       }) 
      } 

      contextMap[contextString] 
     } 

     class QueueContext { 
      def workCount 
      def actor 

      def QueueContext(finishClosure) { 
       workCount = 1 
       actor = Actors.actor { 
        loop { 
         react { closure -> 
          try { 
           closure() 
          } catch (Throwable th) { 
           log.error("Uncaught exception in async queue context", th) 
          } 

          finishClosure() 
         } 
        } 
       } 
      } 

      def send(closure) { 
       actor.send(closure) 
      } 

      def terminate(){ 
       actor.terminate() 
      } 

      def hasWork(incrementWork) { 
       workCount += (incrementWork ? 1 : -1) 
       workCount > 0 
      } 
     } 
    } 
} 
0

Нет, явно созданные пулы не завершаются сами по себе. Вы должны вызывать shutdown() для них явно.

Использование команды withPool() {} гарантирует, что пул будет уничтожен после завершения кода.

+0

Я смущен. Кажется, что и withPool, и с использованием ExistingPool. Я сделал несколько тестов и логики после закрытия, как только пул закончил. Это не то, что я хочу. Я не хочу, чтобы пул блокировал выполнение. – Taplar

+0

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

+0

Я считаю, что у нас есть рабочее решение с участием актеров. Я отправлю свое окончательное решение, как только мы уверены, что мы довольны этим, :) – Taplar

Смежные вопросы