2016-01-21 67 views
0

在使用reactivemongo向mongoDB寫入文檔的db對象中,我有以下功能。在發送成功的JSON響應之前等待數據庫事務結果

def writeDocument(json: JsValue):Future[WriteResult] = { 

    def collection: JSONCollection = { 
    val driver = new MongoDriver 
    val connection = driver.connection(List("localhost")) 
    val db = connection("superman") 
    db.collection[JSONCollection]("Powers") 
    } 

val document = json.as[JsObject] 
val future = collection.insert(document) 
future.onComplete { 
    case Failure(e) => { 
    logger.error("""Message="Database is not reachable." """ + """ transactionID=""" + (json \\ "transactionID") + " errorResponse=" + e.getLocalizedMessage) 
    throw e} 
    case Success(result) => 
    println("successfully inserted document with result = " + result) 
} 
future 
} 

在控制器側,我有它調用上述writeDocument()功能這部分代碼。由於reactivemongo是異步的,所以即使數據庫不存活,我也總是會獲得成功的JSON消息。我知道數據庫寫入正在通過Futures進行,我如何才能確保只有在數據成功寫入數據庫後才能發送成功的響應?

def validateRequest(json: JsValue): Result = { 

{ 
    val logger = LoggerFactory.getLogger("superman") 
    val jsonSchema = Source.fromURL(getClass.getResource("/schema.json")).getLines.mkString 
    val transactionID = (json \ "transactionID").get 
    val result: VA[JsValue] = SchemaValidator.validate(Json.fromJson[SchemaType](
    Json.parse(jsonSchema.stripMargin)).get, json) 

    result.fold(
    invalid = { errors => 

     var violatesList = List[String]() 
     val invalidError = Json.obj("transactionID" -> transactionID, "status" -> "error", "description" -> "Invalid Request Received") 
     for (msg <- (errors.toJson \\ "msgs")) { 
     violatesList = (msg(0).get).as[String] :: violatesList 
     } 
     val errorResponse = Json.toJson(invalidError ++ Json.obj("violations" -> violatesList)) 
     logger.error("""Message="Invalid Request Received" for transactionID=""" + transactionID.toString() + "errorResponse:" + errorResponse) 
     BadRequest(errorResponse) 

    }, 

    valid = { 
     post => 
     val insertResult = db.writeDocument(json) 
     insertResult.map{ result => 
      val json = Json.obj("transactionID" -> transactionID.toString, 
      "status" -> "OK", "message" -> ("Valid Request Received")) 
      Ok(json) 
     }.recover{ case error: Throwable => 
      val json = Json.obj("transactionID" -> transactionID.toString, 
      "status" -> "FAILED") 
      Ok(json) 
     } 




) 
} 

}

回答

1

你需要做以下修改:

1.At的writeDocument,而不是末端(或除爲了直接處理未來,你應該回報未來。

2.In控制器,你應該對未來映射到一個響應,通過寫這樣的:當我嘗試返回`future`並添加返回類型

def myAction() = Action.async { request => 
    insertResult.map{ result => 
    val json = Json.obj("transactionID" -> transactionID.toString, 
         "status" -> "OK", "message" -> ("Valid Request Received")) 
    Ok(json) 
    }.recover{ case error: Throwable => 
    val json = Json.obj("transactionID" -> transactionID.toString, 
         "status" -> "FAILED") 
    Ok(json) 
    } 
} 
+0

上得到錯誤'Expression of type Future [Result]與預期的類型_X不一致'請參閱我的Edit 1.我得到'Expression of鍵入Future [結果]不符合期望的類型_X' – summerNight

+0

@summerNight您是否已更新writeDocument()方法以最終返回未來?你能否更新你的問題中的writeDocument()方法來反映? –

+0

我更新了它,並在控制器端添加了該功能的其餘部分 – summerNight

1

簡單地把未來和其映射到想要Result

比賽將盡快承諾被贖回達到這個結果:Play Async

def writeDocument(json: JsValue): Future[LastError] = { 
    // ... 
    future 
} 


valid = { post => 
    val future = db.writeDocument(json) 
    future.map { _ => 
    val successResponse = Json.obj("transactionID" -> transactionID.toString, "status" -> "OK", "message" -> ("Valid Request Received")) 
    Ok(successResponse) 
    } 
} 
+0

'未來[LastError]'時, IDE抱怨'表達式'Future [WriteResult]'不符合期望的類型'Future [LastError]' – summerNight

+0

根據http://reactivemongo.org/releases/0.11/documentation/tutorial/write-documents.html :以前由寫入操作返回的類型Future [LastError]被新API中的Future [WriteResult]所取代。當我嘗試從'writeDocument'返回'Future [WriteResult]'時,我在控制器 – summerNight

相關問題