tweak performance on friendship statuses

This commit is contained in:
Thibault Duplessis 2013-05-20 17:01:25 -03:00
parent cb0f665f33
commit e77ea4fc72
9 changed files with 53 additions and 28 deletions

View file

@ -13,7 +13,8 @@ final class Env(config: Config, system: ActorSystem) {
lazy val preloader = new mashup.Preload(
lobby = Env.lobby.lobby,
history = Env.lobby.history,
featured = Env.game.featured)
featured = Env.game.featured,
friendApi = Env.friend.api)
system.actorOf(Props(new actor.Renderer), name = RendererName)

View file

@ -31,8 +31,8 @@ object Lobby extends LilaController with Results {
tours = TournamentRepo.created,
filter = Env.setup.filter
).map(_.fold(Redirect(_), {
case (preload, entries, posts, tours, featured) status(html.lobby.home(
Json stringify preload, entries, posts, tours, featured)) |> { response
case (preload, entries, posts, tours, featured, requests) status(html.lobby.home(
Json stringify preload, entries, posts, tours, featured, requests)) |> { response
ctx.req.session.data.contains(LilaCookie.sessionId).fold(
response,
response withCookies LilaCookie.makeSessionId(ctx.req)

View file

@ -9,7 +9,8 @@ import lila.forum.PostLiteView
import lila.socket.History
import lila.tournament.Created
import lila.setup.FilterConfig
import lila.user.Context
import lila.user.{ User, Context }
import lila.friend.FriendApi
import controllers.routes
import makeTimeout.large
@ -21,9 +22,10 @@ import play.api.libs.json.{ Json, JsObject, JsArray }
final class Preload(
lobby: ActorRef,
history: History,
featured: Featured) {
featured: Featured,
friendApi: FriendApi) {
private type RightResponse = (JsObject, List[Entry], List[PostLiteView], List[Created], Option[Game])
private type RightResponse = (JsObject, List[Entry], List[PostLiteView], List[Created], Option[Game], List[User])
private type Response = Either[Call, RightResponse]
def apply(
@ -32,12 +34,17 @@ final class Preload(
tours: Fu[List[Created]],
filter: Fu[FilterConfig])(implicit ctx: Context): Fu[Response] =
ctx.isAuth.fold(lobby ? GetOpen, lobby ? GetOpenCasual).mapTo[List[Hook]] zip
timeline zip posts zip tours zip featured.one zip filter map {
case (((((hooks, entries), posts), tours), feat), filter)
timeline zip
posts zip
tours zip
featured.one zip
filter zip
(ctx.userId ?? friendApi.requestersOf) map {
case ((((((hooks, entries), posts), tours), feat), filter), requests)
(Right((Json.obj(
"version" -> history.version,
"pool" -> JsArray(hooks map (_.render)),
"filter" -> filter.render
), entries, posts, tours, feat)))
), entries, posts, tours, feat, requests)))
}
}

View file

@ -0,0 +1,14 @@
@(users: List[User])(implicit ctx: Context)
@if(ctx.isAuth && users.nonEmpty) {
<table>
<tbody>
@users.map { u =>
<tr>
<td>@userLink(u) @shorten(~u.bio, 80)</td>
<td>@friend.button(u.id)</td>
</tr>
}
</tbody>
</table>
}

View file

@ -1,4 +1,4 @@
@(preload: String, timeline: List[lila.timeline.Entry], forumRecent: List[lila.forum.PostLiteView], tours: List[lila.tournament.Created], featured: Option[Game])(implicit ctx: Context)
@(preload: String, timeline: List[lila.timeline.Entry], forumRecent: List[lila.forum.PostLiteView], tours: List[lila.tournament.Created], featured: Option[Game], requests: List[User])(implicit ctx: Context)
@underchat = {
<div id="featured_game">
@ -16,6 +16,7 @@
title = "",
baseline = baseline.some,
active = siteMenu.play.some,
goodies = requests.nonEmpty.option(views.html.friend.quickRequests(requests)),
underchat = underchat.some) {
<div id="call_boxes">
@translationCall.map(i18n.callBox(_))

View file

@ -8,12 +8,13 @@ private[friend] final class Cached {
val friendIds = AsyncCache(FriendRepo.friendUserIds, maxCapacity = 5000)
// UserId => List[UserId] wanted friends of that user
val requestIds = AsyncCache(RequestRepo.requestedUserIds, maxCapacity = 5000)
val requestedIds = AsyncCache(RequestRepo.requestedUserIds, maxCapacity = 5000)
val nbRequests = AsyncCache(RequestRepo.countByFriendId, maxCapacity = 5000)
// UserId => List[UserId] wanabe friends of that user
val requesterIds = AsyncCache(RequestRepo.requesterUserIds, maxCapacity = 5000)
private[friend] def invalidate(userId: ID): Funit =
friendIds.remove(userId) >>
requestIds.remove(userId) >>
nbRequests.remove(userId)
requestedIds.remove(userId) >>
requesterIds.remove(userId)
}

View file

@ -15,15 +15,17 @@ final class FriendApi(cached: Cached) {
cached friendIds u1 map (_ contains u2)
def requests(u1: ID, u2: ID): Fu[Boolean] =
cached requestIds u1 map (_ contains u2)
cached requestedIds u1 map (_ contains u2)
def quickStatus(u1: ID, u2: ID): Fu[QuickStatus] =
areFriends(u1, u2) zip requests(u1, u2) zip requests(u2, u1) map {
case ((true, _), _) QuickStatus(u1, u2, true, none)
case ((_, true), _) QuickStatus(u1, u2, false, true.some)
case ((_, _), true) QuickStatus(u1, u2, false, false.some)
case _ QuickStatus(u1, u2, false, none)
}
areFriends(u1, u2) zip
(cached requestedIds u1 map (_ contains u2)) zip
(cached requesterIds u1 map (_ contains u2)) map {
case ((true, _), _) QuickStatus(u1, u2, true, none)
case ((_, true), _) QuickStatus(u1, u2, false, true.some)
case ((_, _), true) QuickStatus(u1, u2, false, false.some)
case _ QuickStatus(u1, u2, false, none)
}
def friendsOf(userId: ID): Fu[List[User]] =
cached friendIds userId flatMap UserRepo.byIds map { _ sortBy (_.id) }
@ -48,12 +50,8 @@ final class FriendApi(cached: Cached) {
case _ fufail("[friend] no request nor friendship to revoke")
}
def requestsWithUsers(userId: ID): Fu[List[RequestWithUser]] = for {
requests RequestRepo findByFriendId userId
users $find.byOrderedIds[User](requests.map(_.user))
} yield requests zip users map {
case (request, user) RequestWithUser(request, user)
}
def requestersOf(userId: ID): Fu[List[User]] =
cached requesterIds userId flatMap $find.byIds[User]
private[friend] def makeFriends(u1: ID, u2: ID): Funit =
FriendRepo.add(u1, u2) >> invalidate(u1, u2)

View file

@ -18,7 +18,7 @@ private[friend] object FriendRepo {
_.flatten filterNot (userId ==)
}
def add(u1: ID, u2: ID): Funit = $insert(Friend.make(u1, u2).pp)
def add(u1: ID, u2: ID): Funit = $insert(Friend.make(u1, u2))
def remove(u1: ID, u2: ID): Funit = $remove byId Friend.makeId(u1, u2)
}

View file

@ -21,6 +21,9 @@ private[friend] object RequestRepo {
def requestedUserIds(u: ID): Fu[List[String]] =
$primitive(userIdQuery(u), "friend")(_.asOpt[String])
def requesterUserIds(u: ID): Fu[List[String]] =
$primitive(friendIdQuery(u), "user")(_.asOpt[String])
def countByFriendId(friendId: String): Fu[Int] =
$count(friendIdQuery(friendId))