better recover of mongodb duplicate key errors

This commit is contained in:
Thibault Duplessis 2015-07-15 12:51:49 +02:00
parent e7685929bf
commit 48c633c6b0
8 changed files with 21 additions and 24 deletions

View file

@ -8,4 +8,12 @@ package object db extends PackageObject with WithPlay {
type JsTubeInColl[A] = JsTube[A] with InColl[A]
type BsTubeInColl[A] = BsTube[A] with InColl[A]
private val duplicateKeyMessage = "duplicate key error"
import reactivemongo.api.commands.WriteResult
def recoverDuplicateKey[A](f: WriteResult => A): PartialFunction[Throwable, A] = {
case e: WriteResult if e.getMessage.contains(duplicateKeyMessage) => f(e)
}
}

View file

@ -24,10 +24,8 @@ final class DonationApi(coll: Coll, monthlyGoal: Int) {
)).cursor[Donation]()
.collect[List](nb)
def create(donation: Donation) = coll insert donation recover {
case e: reactivemongo.core.commands.LastError if e.getMessage.contains("duplicate key error") =>
println(e.getMessage)
} void
def create(donation: Donation) = coll insert donation recover
lila.db.recoverDuplicateKey(e => println(e.getMessage)) void
// in $ cents
def donatedByUser(userId: String): Fu[Int] =

View file

@ -21,17 +21,16 @@ final class CrosstableApi(coll: Coll) {
}
def apply(u1: String, u2: String): Fu[Option[Crosstable]] =
coll.find(select(u1, u2)).one[Crosstable] orElse create(u1, u2) recover {
case e: reactivemongo.core.commands.LastError if e.getMessage.contains("duplicate key error") => none
}
coll.find(select(u1, u2)).one[Crosstable] orElse create(u1, u2) recoverWith
lila.db.recoverDuplicateKey(_ => coll.find(select(u1, u2)).one[Crosstable])
def nbGames(u1: String, u2: String): Fu[Int] =
coll.find(
select(u1, u2),
BSONDocument("n" -> true)
).one[BSONDocument] map {
~_.flatMap(_.getAs[Int]("n"))
}
~_.flatMap(_.getAs[Int]("n"))
}
def add(game: Game): Funit = game.userIds.distinct.sorted match {
case List(u1, u2) =>

View file

@ -20,9 +20,8 @@ final class MongoCache[K, V: MongoCache.Handler] private (
def apply(k: K): Fu[V] = cache(k) {
coll.find(select(k)).one[Entry] flatMap {
case None => f(k) flatMap { v =>
coll.insert(makeEntry(k, v)) recover {
case e: reactivemongo.core.commands.LastError if e.getMessage.contains("duplicate key error") => ()
} inject v
coll.insert(makeEntry(k, v)) recover
lila.db.recoverDuplicateKey(_ => ()) inject v
}
case Some(entry) => fuccess(entry.v)
}

View file

@ -41,9 +41,7 @@ private[opening] final class Finisher(
)) ++ BSONDocument("$set" -> BSONDocument(
Opening.BSONFields.perf -> Perf.perfBSONHandler.write(openingPerf)
))) zip UserRepo.setPerf(user.id, "opening", userPerf)
}) recover {
case e: reactivemongo.core.commands.LastError if e.getMessage.contains("duplicate key error") => ()
} inject (a -> none)
}) recover lila.db.recoverDuplicateKey(_ => ()) inject (a -> none)
}
}

View file

@ -45,9 +45,7 @@ private[puzzle] final class Finisher(
)) ++ BSONDocument("$set" -> BSONDocument(
Puzzle.BSONFields.perf -> Perf.perfBSONHandler.write(puzzlePerf)
))) zip UserRepo.setPerf(user.id, "puzzle", userPerf)
}) recover {
case e: reactivemongo.core.commands.LastError if e.getMessage.contains("duplicate key error") => ()
} inject (a -> none)
}) recover lila.db.recoverDuplicateKey(_ => ()) inject (a -> none)
}
private val VOLATILITY = Glicko.default.volatility

View file

@ -120,9 +120,7 @@ final class TeamApi(
).toFollowersOf(userId).toUsers(previousMembers))
}
}
} recover {
case e: reactivemongo.core.commands.LastError if e.getMessage.contains("duplicate key error") =>
}
} recover lila.db.recoverDuplicateKey(e => ())
def quit(teamId: String)(implicit ctx: UserContext): Fu[Option[Team]] = for {
teamOption $find.byId[Team](teamId)

View file

@ -152,9 +152,8 @@ private[video] final class VideoApi(
View.BSONFields.id -> View.makeId(videoId, userId)
)).one[View]
def add(a: View) = (viewColl insert a).void recover {
case e: reactivemongo.core.commands.LastError if e.getMessage.contains("duplicate key error") => ()
}
def add(a: View) = (viewColl insert a).void recover
lila.db.recoverDuplicateKey(_ => ())
def hasSeen(user: User, video: Video): Fu[Boolean] =
viewColl.count(BSONDocument(