播放mongo枚举器意外停止

时间:2015-01-19 18:35:41

标签: scala akka reactive-programming reactivemongo

设置Scala 2.11.4,Playframework 2.3.7,Reacivemongo(0.10.5.0.akka23 / 0.11.0-SNAPSHOT同时尝试过)。

我们有一个拥有18,000个实体的集合,使用Enumerator / Iteratee方法以异步方式处理此集合。

案例1。 处理很简单(将实体提取为CSV格式并将其作为REST响应以块的形式发送)一切正常,所有记录都被提取和处理。

案例2。 处理涉及最多需要10秒的计算,并在计算后更新记录,使用foreach Iteratee进行计算,Iteratee更新内部任务跟踪器中已处理实体的数量。处理可能需要一段时间,但没关系

        Patient.findByClient(clientName) &>
            Enumeratee.mapM(patient => {
                val evaluatedAndSaveTask = patient.
                    evaluate(parser).
                    flatMap(patientOpt =>
                        patientOpt.
                            map(evaluatedPatient => evaluatedPatient.saveAndGet().map(Some(_))).
                            getOrElse(Future.successful(None))
                    )
                evaluatedAndSaveTask.recover({
                    case t =>
                        t.printStackTrace()
                        None
                })
            })
        // Step 2.1. Running evaluation process through Iteratee
        val evaluationTask = evaluation run Iteratee.foreach(patientOpt => {
            collection.update(Json.obj("clientName" -> clientName), Json.obj("$inc" -> Json.obj("processedPatients" -> 1))))
        )
        // Step 2.3. Log errors
        evaluationTask.onSuccess({ case _ => Patient.LOG.info("PatientEvaluation DONE") })
        evaluationTask.onFailure({ case t => {
            t.printStackTrace();
            Patient.LOG.info("PatientEvaluation FAILED");
        }})

在这种情况下,只有575个实体得到处理,Iteratee结束打印出“患者评估完成”。

我从等式中删除了保存,但没有帮助。

为什么会这样?

1 个答案:

答案 0 :(得分:3)

我终于找到了问题的罪魁祸首--Mono在超时后自动过期评估,你可以指定noCursorTimeout标志,以防止这种情况:

        collection.
            find(findQ).
            sort(if(sortQF.values.isEmpty) sortQ else sortQF).
            options(QueryOpts(skipN = offset + page._1 * page._2).noCursorTimeout).
            cursor[T].

出于某种原因,ReactiveMongo在这种情况下不会抛出异常,只关闭Iterator。我在此之后在ReactiveMongo https://github.com/ReactiveMongo/ReactiveMongo/issues/250中创建了一个问题。

现在,对我来说,使光标过期可能更安全,并使用偏移重启。