【问题标题】:Executing grails service method in separate thread在单独的线程中执行 grails 服务方法
【发布时间】:2016-12-29 19:48:00
【问题描述】:

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

【问题讨论】:

  • 愚蠢、反动、错误的标题。 Grails 并发性并没有从根本上被破坏。如果是这样,就会出现一些提示 - 测试失败,有人使用快照构建进行开发和/或测试,等等。
  • 好吧,你说得对,我改了标题。谢谢

标签: multithreading grails concurrency


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-24
    • 2021-06-09
    • 1970-01-01
    • 1970-01-01
    • 2019-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多