parallelize user infos creation

pull/83/head
Thibault Duplessis 2013-05-23 20:03:43 +02:00
parent 8b30d8c90e
commit bc7c02203e
6 changed files with 62 additions and 49 deletions

View File

@ -15,6 +15,12 @@ final class Env(config: Config, system: ActorSystem) {
history = Env.lobby.history,
featured = Env.game.featured)
lazy val userInfo = mashup.UserInfo(
countUsers = () Env.user.countEnabled,
bookmarkApi = Env.bookmark.api,
eloCalculator = Env.round.eloCalculator,
relationApi = Env.relation.api) _
system.actorOf(Props(new actor.Renderer), name = RendererName)
system.actorOf(Props(new actor.Router(

View File

@ -15,10 +15,6 @@ object User extends LilaController {
private def env = Env.user
private def gamePaginator = Env.game.paginator
private def forms = lila.user.DataForm
private lazy val makeUserInfo = mashup.UserInfo(
countUsers = () env.countEnabled,
bookmarkApi = Env.bookmark.api,
eloCalculator = Env.round.eloCalculator) _
def show(username: String) = Open { implicit ctx
isXhr.fold(mini(username), filter(username, "all", 1))
@ -36,14 +32,12 @@ object User extends LilaController {
private def userShow(u: UserModel, filterName: String, page: Int)(implicit ctx: Context) =
(u.enabled || isGranted(_.UserSpy)).fold({
for {
info makeUserInfo(u, ctx)
info Env.current.userInfo(u, ctx)
filters = mashup.GameFilterMenu(info, ctx.me, filterName)
pag (filters.query.fold(Env.bookmark.api.gamePaginatorByUser(u, page)) { query
gamePaginator.recentlyCreated(query, filters.cachedNb)(page)
})
nbFollowing Env.relation.api nbFollowing u.id
nbFollowers Env.relation.api nbFollowers u.id
} yield html.user.show(u, info, pag, nbFollowing, nbFollowers, filters)
} yield html.user.show(u, info, pag, filters)
}, fuccess(html.user.disabled(u)))
private def mini(username: String)(implicit ctx: Context) =
@ -70,7 +64,7 @@ object User extends LilaController {
def opponents(username: String) = Open { implicit ctx
OptionFuOk(UserRepo named username) { user
mashup.UserInfo.bestOpponents(user.id, 50) map { ops
lila.game.BestOpponents(user.id, 50) map { ops
html.user.opponents(user, ops)
}
}

View File

@ -5,6 +5,7 @@ import chess.{ EloCalculator, Color }
import lila.game.{ GameRepo, Game }
import lila.user.{ User, UserRepo, Context, EloChart }
import lila.bookmark.BookmarkApi
import lila.relation.RelationApi
case class UserInfo(
user: User,
@ -13,7 +14,9 @@ case class UserInfo(
nbWithMe: Option[Int],
nbBookmark: Int,
eloWithMe: Option[List[(String, Int)]],
eloChart: Option[EloChart]) {
eloChart: Option[EloChart],
nbFollowing: Int,
nbFollowers: Int) {
def nbRated = user.nbRatedGames
@ -27,43 +30,37 @@ object UserInfo {
def apply(
countUsers: () Fu[Int],
bookmarkApi: BookmarkApi,
eloCalculator: EloCalculator)(user: User, ctx: Context): Fu[UserInfo] = for {
rank (user.elo >= rankMinElo) ?? {
eloCalculator: EloCalculator,
relationApi: RelationApi)(user: User, ctx: Context): Fu[UserInfo] =
((user.elo >= rankMinElo) ?? {
UserRepo rank user flatMap { rank
countUsers() map { nbUsers (rank -> nbUsers).some }
}
}
nbPlaying (ctx is user) ?? {
GameRepo count (_ notFinished user.id) map (_.some)
}
nbWithMe ctx.me.filter(user!=) ?? { me
GameRepo count (_.opponents(user, me)) map (_.some)
}
nbBookmark bookmarkApi countByUser user
eloChart EloChart(user)
eloWithMe = ctx.me.filter(user !=) map { me
List(
"win" -> eloCalculator.diff(me, user, Color.White.some),
"draw" -> eloCalculator.diff(me, user, None),
"loss" -> eloCalculator.diff(me, user, Color.Black.some))
}
} yield new UserInfo(
user = user,
rank = rank,
nbPlaying = ~nbPlaying,
nbWithMe = nbWithMe,
nbBookmark = nbBookmark,
eloWithMe = eloWithMe,
eloChart = eloChart)
def bestOpponents(userId: String, limit: Int): Fu[List[(User, Int)]] =
GameRepo.bestOpponents(userId, limit) flatMap { opponents
UserRepo enabledByIds opponents.map(_._1) map { users
(users map { user
opponents find (_._1 == user.id) map { opponent
user -> opponent._2
}
}).flatten sortBy (-_._2)
}) zip
((ctx is user) ?? {
GameRepo count (_ notFinished user.id) map (_.some)
}) zip
(ctx.me.filter(user!=) ?? { me
GameRepo count (_.opponents(user, me)) map (_.some)
}) zip
(bookmarkApi countByUser user) zip
EloChart(user) zip
relationApi.nbFollowing(user.id) zip
relationApi.nbFollowers(user.id) map {
case ((((((rank, nbPlaying), nbWithMe), nbBookmark), eloChart), nbFollowing), nbFollowers) new UserInfo(
user = user,
rank = rank,
nbPlaying = ~nbPlaying,
nbWithMe = nbWithMe,
nbBookmark = nbBookmark,
eloWithMe = ctx.me.filter(user !=) map { me
List(
"win" -> eloCalculator.diff(me, user, Color.White.some),
"draw" -> eloCalculator.diff(me, user, None),
"loss" -> eloCalculator.diff(me, user, Color.Black.some))
},
eloChart = eloChart,
nbFollowing = nbFollowing,
nbFollowers = nbFollowers)
}
}
}

View File

@ -1,4 +1,4 @@
@(u: User, info: lila.app.mashup.UserInfo, games: Paginator[Game], nbFollowing: Int, nbFollowers: Int, filters: lila.app.mashup.GameFilterMenu)(implicit ctx: Context)
@(u: User, info: lila.app.mashup.UserInfo, games: Paginator[Game], filters: lila.app.mashup.GameFilterMenu)(implicit ctx: Context)
@title = @{ "%s : %s - page %d".format(u.username, userGameFilterTitle(info, filters.current), games.currentPage) }
@ -60,8 +60,8 @@ evenMoreCss = evenMoreCss) {
}
</div>
<div class="social">
<a href="@routes.Relation.following(u.username)">@trans.nbFollowing(nbFollowing)</a>
<a href="@routes.Relation.followers(u.username)">@trans.nbFollowers(nbFollowers)</a>
<a href="@routes.Relation.following(u.username)">@trans.nbFollowing(info.nbFollowing)</a>
<a href="@routes.Relation.followers(u.username)">@trans.nbFollowers(info.nbFollowers)</a>
@if(ctx.isAuth && !ctx.is(u)) {
@relation.actions(u.id)
}

View File

@ -0,0 +1,17 @@
package lila.game
import lila.user.{ User, UserRepo }
object BestOpponents {
def apply(userId: String, limit: Int): Fu[List[(User, Int)]] =
GameRepo.bestOpponents(userId, limit) flatMap { opponents
UserRepo enabledByIds opponents.map(_._1) map { users
(users map { user
opponents find (_._1 == user.id) map { opponent
user -> opponent._2
}
}).flatten sortBy (-_._2)
}
}
}

1
todo
View File

@ -66,7 +66,6 @@ from MoralIntentions email:
- The possibility of team matches (with solutions for players who are in several teams), where the team leader has to choose the board order, where the team results are shown and where the team player (who has played all of the games of the match) with the highest Percentage Score gets crowned Player of the Match of team "A".
safari has high bounce rate
send message to sockets when a friendship is created or revoked
convert background board css to single image (needs gimp)
correspondance chess http://en.lichess.org/forum/lichess-feedback/correspondence-chess#1
takeback/enpassant glitch http://en.lichess.org/forum/lichess-feedback/i-found-a-glitch#1
show teams in user mini