2014-10-14 3 views
0

У меня есть приложение Grails (версия 2.4.3), и у меня есть проблема с вызовом метода службы в отдельном потоке. Я использую концепцию Promise в соответствии с документацией. У меня есть две службы: в первом у меня есть основной метод, который сохраняет родительский объект, а затем второй сохраняет записи детей для данного родителя. Я хотел бы реализовать сохранение записей детей в отдельном потоке. Основная услуга выглядит следующим образом:Выполнение метода обслуживания grails в отдельной строке

@Transactional 
class ParentService { 

    AsyncSourceService asyncSourceService 


Parent save(Date dateFrom, Date dateTill, File sourceFile){ 
     log.info "save - start" 

     Parent parent = new Parent(dateFrom: dateFrom, dateTill: dateTill, status: Status.LOAD_IN_PROGRESS) 
     parent.save(flush:true) 

     //TODO: asynchronous call 
     //sourceRecordService.decodeRecords(parent, sourceFile) 

      def promise = asyncSourceService.decodeSourceFile(Parent, sourceFile) 
      promise.onComplete { results -> 
       println("#### Results: $results ####") 
      } 
      promise.onError { Throwable t -> 
       //t.printStackTrace() 
       println "####### ${t.message}" 
      } 
     return parent 
    } 
} 

SourceService выглядит следующим образом:

@Transactional 
class SourceService { 

    Integer decodeSourceFile(Parent parent, File sourceFile){ 
     int lineNo = 0 
     sourceFile.eachLine {line-> 
      // convert line to record 
      sourceRecord.save() 
      lineNo++ 
     } 
     return new IntegerlineNo 

    } 
} 

И обертка для асинхронного вызывающей службы выглядит следующим образом:

class AsyncSourceervice { 

    @DelegateAsync 
    SourceService sourceService 

    Promise<Integer> decodeSourceFile(Parent parent, File sourceFile){ 
     Promises.task { 
      sourceService.decodeSourceFile(parent, sourceFile) 
     } 
    } 
} 

И это не работает. Когда я запускаю процесс я получаю:

| Error 2014-10-14 08:47:26,586 [Actor Thread 2] ERROR gpars.LoggingPoolFactory - Async execution error: null 
Message: null                         
    Line | Method                        
->> 72 | doCall in org.grails.async.factory.gpars.GparsPromise$_onError_closure2       
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -           
|  62 | run  in groovyx.gpars.dataflow.DataCallback$1             
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor             
| 615 | run  in java.util.concurrent.ThreadPoolExecutor$Worker           
^ 744 | run . . . in java.lang.Thread 

Я знаю, что метод сервиса для декодирования работ и декодирует надлежащее количество записей, но ни один метод обратного вызова не происходит (ни на OnError или OnComplete). Что не так? Я заметил, что для файла с несколькими записями (менее 50) он отлично работает, но когда файл содержит около 100 записей или более, я получаю такую ​​дорожку стека. Кажется, это странно, потому что мой отладочный файл показывает, что процесс декодирования отлично работает и возвращает правильное значение декодированных записей. И когда я называю весь процесс тем же самым потоком, все кажется правильным. Кто-нибудь знает, что не так? Буду благодарен за любое предложение. возможно, я должен использовать другое решение. Который?

+0

Немой, реакционный, неправильный заголовок. Параллелизм Grails принципиально не нарушен. Если бы это было так, некоторый намек показал бы себя - неудачный тест, кто-то, использующий сборку моментальных снимков для разработки и/или тестирования, и т. Д. –

+0

Хорошо, вы правы, я изменил название. благодаря –

ответ

0

Я нашел решение: когда я комментирую обработку onError и onComplete для объекта обещания, все работает нормально. Кажется, что эти обработчики выполняются до завершения потока, поэтому для больших файлов у меня есть исключение. Я думаю, если это ошибка в концепции Promise или если я ошибаюсь, то это не так.

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