我正在使用Scala,Play Framework 2.1.x和reactivemongo驱动程序.
我有一个api电话:
def getStuff(userId: String) = Action(implicit request => {
Async {
UserDao().getStuffOf(userId = userId).toList() map {
stuffLst => Ok(stuffLst)
}
}
})
Run Code Online (Sandbox Code Playgroud)
它在99%的时间内工作正常,但有时可能会失败(无关紧要的原因,这不是问题).
我想在出现错误的情况下恢复,所以我补充说:
recover { case _ => BadRequest("")}
Run Code Online (Sandbox Code Playgroud)
但这并没有让我从错误中恢复过来.
我在scala控制台上尝试了相同的概念并且它有效:
import scala.concurrent._
import scala.concurrent.duration._
import ExecutionContext.Implicits.global
var f = future { throw new Exception("") } map {_ => 2} recover { case _ => 1}
Await.result(f, 1 nanos)
Run Code Online (Sandbox Code Playgroud)
这将按预期返回1.
我目前用以下方法包装Async:
try{
Async {...}
} catch {
case _ => BadRequest("")
}
Run Code Online (Sandbox Code Playgroud)
这就抓住了错误.
我在网上浏览了一些Scala的未来文档,我很困惑为什么恢复不适合我.
有谁知道为什么?我想错过什么来解决它?
我有以下代码在引用时在控制台应用程序中工作 "org.reactivemongo" %% "play2-reactivemongo" % "0.10.5.0.akka23"
当我更新对我的引用时"org.reactivemongo" % "play2-reactivemongo_2.11" % "0.11.0.play23-M3"
:
没有为类型为play.api.libs.json.JsObject的JsObject找到Json序列化程序.尝试为此类型实现隐式OWrites或OFormat.
import org.joda.time.DateTime
import reactivemongo.bson.BSONObjectID
import play.modules.reactivemongo.json.BSONFormats._
case class GoogleToken
(
id: Option[BSONObjectID],
name: String,
emailAddress: String,
refreshToken: String,
expires: DateTime
)
object GoogleToken {
import play.api.libs.json.Json
// Generates Writes and Reads
implicit val googleTokenFormat = Json.format[GoogleToken]
}
Run Code Online (Sandbox Code Playgroud)
然后
val collection = db.collectionJSONCollection
val query = Json.obj()
val cursor = collection.find(query).
cursor[GoogleToken](ReadPreference.nearest).
collect[List]()
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
阅读有关Play Framework和ReactiveMongo的文档让我相信ReactiveMongo的工作方式是它使用很少的线程而且永远不会阻塞.
但是,似乎从Play应用程序到Mongo服务器的通信必须在某个某个线程上发生.这是如何实现的?Play,ReactiveMongo,Akka等源代码的链接也将非常受欢迎.
Play Framework在此页面上包含有关此主题的一些文档,内容涉及线程池.它开始:
Play框架是自下而上的异步Web框架.使用迭代器异步处理流.Play中的线程池被调整为使用比传统Web框架更少的线程,因为play-core中的IO永远不会阻塞.
然后谈谈ReactiveMongo:
典型Play应用程序阻止的最常见位置是它与数据库通信时.遗憾的是,没有一个主要数据库为JVM提供异步数据库驱动程序,因此对于大多数数据库,您唯一的选择是使用阻塞IO.一个值得注意的例外是ReactiveMongo,它是MongoDB的一个驱动程序,它使用Play的Iteratee库与MongoDB进行通信.
以下是关于使用期货的说明:
请注意,您可能想要将您的阻止代码包装在Futures中.这不会使它成为非阻塞,它只是意味着阻塞将在不同的线程中发生.您仍然需要确保您在那里使用的线程池有足够的线程来处理阻塞.
处理异步结果的页面上的Play文档中有类似的注释:
通过将同步IO包装在Future中,您无法神奇地将同步IO变为异步.如果您无法更改应用程序的体系结构以避免阻塞操作,那么在某些时候必须执行操作,并且该线程将阻塞.因此,除了将操作封装在Future中之外,还需要将其配置为在单独的执行上下文中运行,该上下文已配置有足够的线程来处理预期的并发性.
文档似乎说ReactiveMongo是非阻塞的,所以你不必担心它占用你线程池中的很多线程.但ReactiveMongo必须在某处与Mongo服务器通信.
如何实现这种通信,以便Mongo不会使用Play的默认线程池中的线程?
再次,非常感谢Play,ReactiveMongo,Akka等特定文件的链接.
scala reactive-programming playframework iterate reactivemongo
这是一个我想要写入/读取MongoDB的简单JSON:
{
"id": "ff59ab34cc59ff59ab34cc59",
"name": "Joe",
"surname": "Cocker"
}
Run Code Online (Sandbox Code Playgroud)
将其存储在MongoDB中之前,"ff59ab34cc59ff59ab34cc59"
必须被转换成一个ObjectID
和id
更名为_id
...所以获得以下几方面Reads
,我怎么做到这一点?
val personReads: Reads[JsObject] = (
(__ \ 'id).read[String] ~ // how do I rename id to _id AND transform "ff59ab34cc59ff59ab34cc59" to an ObjectID?
(__ \ 'name).read[String] ~
(__ \ 'surname).read[String]
) reduce
Run Code Online (Sandbox Code Playgroud)
当然,我还需要为我的相反Writes
,即重命名_id
,以id
和转化的ObjectID
,格式为纯文本"ff59ab34cc59ff59ab34cc59"
.
调用此异常并且无法解决它...
Error:scalac: missing or invalid dependency detected while loading class file 'GenericCollection.class'.
Could not access term play in package <root>,
because it (or its dependencies) are missing. Check your build definition for
missing or conflicting dependencies. (Re-run with `-Ylog-classpath` to see the problematic classpath.)
A full rebuild may help if 'GenericCollection.class' was compiled against an incompatible version of <root>.
Run Code Online (Sandbox Code Playgroud) 我得到了:
No Json deserializer found for type Option[reactivemongo.bson.BSONObjectID]. Try to implement an implicit Reads or Format for this type.
Run Code Online (Sandbox Code Playgroud)
尝试反序列化我的审阅对象时.
评论:
case class Review(override var id: Option[BSONObjectID] = None,
override var createdAt: Option[DateTime] = None,
override var updatedAt: Option[DateTime] = None,
grade: Int,
text: String,
originIPAddress: Option[String],
status: ReviewStatus,
origin: ReviewOrigin,
rId: Option[Long],
userId: Option[Long]
) extends TemporalModel
object Review {
import mongo_models.enums.EnumFormat._
implicit val reviewStatusReads = enumReads(ReviewStatus)
implicit val reviewOriginReads = enumReads(ReviewOrigin)
implicit val reviewReads: Reads[Review] = (
(__ …
Run Code Online (Sandbox Code Playgroud) 我试图找到在集群工作者之间共享同一个连接池的最佳方法.我有以下结构:
主演员 - >工作人员(最多可达100人) - > MongoDB
在worker和MongoDB之间我想放置reactivemongo,但是我不确定如何在所有actor之间提供连接池共享.
根据reactivemongo文档:
MongoDriver实例管理一个actor系统; 连接管理连接池.通常,MongoDriver或创建MongoConnection永远不会多次实例化.您可以提供一个或多个服务器的列表; 驱动程序将猜测它是独立服务器还是副本集配置.即使有一个副本节点,驱动程序也会探测其他节点并自动添加它们.
我应该在Master actor中创建它然后捆绑每条消息吗?所以,这将是主演员:
val driver = new MongoDriver
val connection = driver.connection(List("localhost"))
Run Code Online (Sandbox Code Playgroud)
然后我将连接传递给消息中的actor.或者我应该查询每个Work Actor中的连接并在消息中仅传递驱动程序?
非常感谢任何帮助.谢谢.
我已经开始使用Play和Play-ReactiveMongo插件,并在GET"document by id"场景中测试404响应.不幸的是,而不是Play返回404 NotFound响应,我得到了这个异常:
java.util.NoSuchElementException: JsError.get
at play.api.libs.json.JsError.get(JsResult.scala:11) ~[play_2.10.jar:2.1.1]
at play.api.libs.json.JsError.get(JsResult.scala:10) ~[play_2.10.jar:2.1.1]
at play.modules.reactivemongo.json.collection.JSONGenericHandlers$StructureBufferWriter$.write(jsoncollection.scala:44) ~[play2-reactivemongo_2.10-0.9.jar:0.9]
at play.modules.reactivemongo.json.collection.JSONGenericHandlers$StructureBufferWriter$.write(jsoncollection.scala:42) ~[play2-reactivemongo_2.10-0.9.jar:0.9]
at reactivemongo.api.collections.GenericQueryBuilder$class.reactivemongo$api$collections$GenericQueryBuilder$$write(genericcollection.scala:323) ~[reactivemongo_2.10-0.9.jar:0.9]
at reactivemongo.api.collections.GenericQueryBuilder$class.cursor(genericcollection.scala:333) ~[reactivemongo_2.10-0.9.jar:0.9]
Run Code Online (Sandbox Code Playgroud)
如果id参数与现有文档匹配,则下面的getById函数成功返回单个文档,如果找不到文档,则在"one [JsValue]"行上成功返回异常.
路线文件:
GET /items/:id controllers.ItemsController.getById(id: String)
Run Code Online (Sandbox Code Playgroud)
控制器对象:
object ItemsController extends Controller with MongoController {
def itemsCollection: JSONCollection = db.collection[JSONCollection]("items")
def getById(id: String) = Action {
Async {
val query = Json.obj("_id" -> Json.obj("$oid" ->id))
val futureItem = itemsCollection.
find(query).
one[JsValue]
futureItem.map {
case Some(item) => Ok(item)
case None => NotFound(Json.obj("message" -> …
Run Code Online (Sandbox Code Playgroud) 我最近将Play升级到版本2.3.5并尝试将其与ReactiveMongo一起使用.但是,每当我尝试从mongoDB读取数据时,都会发生异常.这是我的build.sbt:
name := """ReactiveMongoRestExample"""
version := "1.0-SNAPSHOT"
lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.11.1"
libraryDependencies ++= Seq(
jdbc,
anorm,
cache,
ws,
"org.reactivemongo" %% "play2-reactivemongo" % "0.10.5.0.akka23"
)
Run Code Online (Sandbox Code Playgroud)
这是堆栈跟踪:
play.api.Application $$匿名$ 1:执行异常[PrimaryUnavailableException $:MongoError [ '没有主节点可用!']]]在play.api.Application $ class.handleError(Application.scala:296)〜[play_2 .11-2.3.5.jar:2.3.5] at play.api.DefaultApplication.handleError(Application.scala:402)[play_2.11-2.3.5.jar:2.3.5] at play.core.server. netty.PlayDefaultUpstreamHandler $$ anonfun $ 14 $$ anonfun $ $申请1.applyOrElse(PlayDefaultUpstreamHandler.scala:205)[play_2.11-2.3.5.jar:2.3.5]在play.core.server.netty.PlayDefaultUpstreamHandler $$ anonfun在scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:36)[阶库$ 14 $$ anonfun $ $申请1.applyOrElse(PlayDefaultUpstreamHandler.scala::202)[2.3.5 play_2.11-2.3.5.jar] -2.11.2.jar:在reactivemongo.core.actors.Exceptions $ PrimaryUnavailableException $ MongoError [ '没有主节点可用!'(actors.scala:reactivemongo.core.actors.Exceptions $ PrimaryUnavailableException $:NA]所致. )〜[reactivemongo_2.11-0.10.5.0.akka23.jar:0.10.5.0.akka23]在reactivemongo.core.actors.MongoDBSystem $$ anonfun $ $ pickChannel 4.适用(actors.scala:508)〜[reactivemongo_2.11-0.10.5.0.akka23.jar:0.10.5.0.akka23]在reactivemongo. core.actors.MongoDBSystem $$ …
我已经开始通过创建一个简单的Scala项目来学习reactivemongo.我从SBT开始.这是我的build.sbt
档案:
name := "mongo-test"
version := "1.0"
scalaVersion := "2.10.2"
libraryDependencies ++= Seq(
"org.reactivemongo" %% "reactivemongo" % "0.9"
)
Run Code Online (Sandbox Code Playgroud)
但是我在执行compile命令时遇到错误:
[info] Resolving play#play-iteratees_2.10;2.1.0 ...
[warn] module not found: play#play-iteratees_2.10;2.1.0
[warn] ==== local: tried
[warn] /home/amir/.ivy2/local/play/play-iteratees_2.10/2.1.0/ivys/ivy.xml
[warn] ==== public: tried
[warn] http://repo1.maven.org/maven2/play/play-iteratees_2.10/2.1.0/play-iteratees_2.10-2.1.0.pom
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: play#play-iteratees_2.10;2.1.0: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
Run Code Online (Sandbox Code Playgroud)
更新:我的SBT版本是0.13.0.