在单独的线程中执行grails服务方法

时间:2014-10-14 08:03:19

标签: multithreading grails concurrency

我有一个Grails应用程序(版本2.4.3),我在单独的线程中调用服务方法时遇到问题。我根据文档使用Promise概念。我有两个服务:在第一个我有main方法,它保存父实体,然后第二个保存给定父亲的子记录。我想在单独的线程中实现保存子记录。主要服务如下:

@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条记录或更多时,我得到了这样的堆栈跟踪。这看起来很奇怪,因为我的调试显示解码过程工作正常,并返回正确的解码记录值。当我在同一个线程中调用整个过程时,每个事情似乎都是正确的。 有谁知道出了什么问题?我将不胜感激任何建议。也许我应该使用其他解决方案。哪个?

1 个答案:

答案 0 :(得分:0)

我找到了解决方案:当我为promise对象处理onError和onComplete时,一切正常。似乎这些处理程序在线程完成之前执行,这就是为什么对于较大的文件我得到了异常。我正在考虑,如果它是Promise概念中的错误,或者我错误地理解它。