Skip to content

Commit 2986f44

Browse files
committed
restore the favourite opponents page - with caching
1 parent 1a92e8a commit 2986f44

File tree

7 files changed

+29
-24
lines changed

7 files changed

+29
-24
lines changed

app/controllers/User.scala

+10-17
Original file line numberDiff line numberDiff line change
@@ -235,23 +235,16 @@ object User extends LilaController {
235235
}
236236
}
237237

238-
def opponents(username: String) = Open { implicit ctx =>
239-
OptionFuOk(UserRepo named username) { user =>
240-
lila.game.BestOpponents(user.id, 50) flatMap { ops =>
241-
ctx.isAuth.fold(
242-
Env.pref.api.followables(ops map (_._1.id)),
243-
fuccess(List.fill(50)(true))
244-
) flatMap { followables =>
245-
(ops zip followables).map {
246-
case ((u, nb), followable) => ctx.userId ?? {
247-
relationApi.fetchRelation(_, u.id)
248-
} map { lila.relation.Related(u, nb.some, followable, _) }
249-
}.sequenceFu map { relateds =>
250-
html.user.opponents(user, relateds)
251-
}
252-
}
253-
}
254-
}
238+
def opponents = Auth { implicit ctx => me =>
239+
for {
240+
ops <- Env.game.bestOpponents(me.id)
241+
followables <- Env.pref.api.followables(ops map (_._1.id))
242+
relateds <- ops.zip(followables).map {
243+
case ((u, nb), followable) => relationApi.fetchRelation(me.id, u.id) map {
244+
lila.relation.Related(u, nb.some, followable, _)
245+
}
246+
}.sequenceFu
247+
} yield html.user.opponents(me, relateds)
255248
}
256249

257250
def perfStat(username: String, perfKey: String) = Open { implicit ctx =>

app/views/base/layout.scala.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ <h1>
185185
<div class="content list"></div>
186186
<div class="nobody@if(ctx.onlineFriends.users.nonEmpty){ none}">
187187
<span>@trans.noFriendsOnline()</span>
188-
<a class="find button" href="@routes.User.opponents(me.username)">
188+
<a class="find button" href="@routes.User.opponents">
189189
<span class="is3 text" data-icon="h">@trans.findFriends()</span>
190190
</a>
191191
</div>

app/views/user/show.scala.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,9 @@ <h1 class="lichess_title user_link @if(isOnline(u.id)){online}else{offline}">
200200
<a href="@routes.Account.profile" title="@trans.editProfile()">
201201
Profile completion: @profile.completionPercent%
202202
</a>
203+
<br />
204+
<a href="@routes.User.opponents">@trans.favoriteOpponents()</a>
203205
}
204-
<!-- <a href="@routes.User.opponents(u.username)">@trans.favoriteOpponents()</a> -->
205206
<br />
206207
<br />
207208
<p>@trans.tpTimeSpentPlaying(showPeriod(info.playTime.totalPeriod))</p>

conf/routes

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ GET /insights/:username/:metric/:dimension/*filters controllers.Insight.path(u
5151
GET /@/:username/tournaments/:path controllers.UserTournament.path(username: String, path: String, page: Int ?= 1)
5252

5353
# User
54-
GET /@/:username/opponents controllers.User.opponents(username: String)
5554
GET /@/:username/mod controllers.User.mod(username: String)
5655
POST /@/:username/note controllers.User.writeNote(username: String)
5756
GET /@/:username/mini controllers.User.showMini(username: String)
@@ -60,6 +59,7 @@ GET /@/:username/perf/:perfKey controllers.User.perfStat(username: Strin
6059
GET /@/:username/:filterName controllers.User.showFilter(username: String, filterName: String, page: Int ?= 1)
6160
GET /@/:username controllers.User.show(username: String)
6261
GET /player/myself controllers.User.myself
62+
GET /player/opponents controllers.User.opponents
6363
GET /player controllers.User.list
6464
GET /player/top/200/:perfKey controllers.User.top200(perfKey: String)
6565
GET /player/top/week controllers.User.topWeek

modules/game/src/main/BestOpponents.scala

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
package lila.game
22

3+
import com.github.blemale.scaffeine.{ AsyncLoadingCache, Scaffeine }
4+
import scala.concurrent.duration._
5+
36
import lila.user.{ User, UserRepo }
47

5-
object BestOpponents {
8+
final class BestOpponents {
9+
10+
private val limit = 30
11+
12+
private val userIdsCache = Scaffeine()
13+
.expireAfterWrite(15 minutes)
14+
.buildAsyncFuture[User.ID, List[(User.ID, Int)]] { GameRepo.bestOpponents(_, limit) }
615

7-
def apply(userId: String, limit: Int): Fu[List[(User, Int)]] =
8-
GameRepo.bestOpponents(userId, limit) flatMap { opponents =>
16+
def apply(userId: String): Fu[List[(User, Int)]] =
17+
userIdsCache get userId flatMap { opponents =>
918
UserRepo enabledByIds opponents.map(_._1) map {
1019
_ flatMap { user =>
1120
opponents find (_._1 == user.id) map { opponent =>

modules/game/src/main/Env.scala

+2
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ final class Env(
8484
}
8585

8686
lazy val stream = new GameStream(system)
87+
88+
lazy val bestOpponents = new BestOpponents
8789
}
8890

8991
object Env {

modules/game/src/main/GameRepo.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ object GameRepo {
362362

363363
// #TODO expensive stuff, run on DB replica
364364
// Can't be done on reactivemongo 0.11.9 :(
365-
def bestOpponents(userId: String, limit: Int): Fu[List[(String, Int)]] = {
365+
private[game] def bestOpponents(userId: String, limit: Int): Fu[List[(User.ID, Int)]] = {
366366
import reactivemongo.api.collections.bson.BSONBatchCommands.AggregationFramework._
367367
coll.aggregate(Match($doc(F.playerUids -> userId)), List(
368368
Match($doc(F.playerUids -> $doc("$size" -> 2))),

0 commit comments

Comments
 (0)