create a single timeline entry per event

This commit is contained in:
Thibault Duplessis 2013-05-24 19:19:08 +02:00
parent f2ac332e10
commit f51ed0c0a4
9 changed files with 32 additions and 35 deletions

View file

@ -76,8 +76,9 @@ print('index forum post authors');
db.f_post.ensureIndex({userId:1}) db.f_post.ensureIndex({userId:1})
print('create timeline_entry collection'); print('create timeline_entry collection');
db.createCollection('timeline_entry'); db.createCollection("timeline_entry",{capped:true,size:50000000})
db.timeline_entry.ensureIndex({user:1, date: -1}); db.timeline_entry.ensureIndex({user:1, date: -1});
db.timeline_entry.ensureIndex({type:1, date: -1});
// print("Reset lobby_room"); // print("Reset lobby_room");
// db.lobby_room.drop(); // db.lobby_room.drop();

View file

@ -8,7 +8,7 @@ import lila.common.paginator._
import lila.db.api._ import lila.db.api._
import lila.db.Implicits._ import lila.db.Implicits._
import lila.db.paginator._ import lila.db.paginator._
import lila.hub.actorApi.timeline.{ MakeEntry, ForumPost } import lila.hub.actorApi.timeline.{ ShareEntry, ForumPost }
import lila.hub.ActorLazyRef import lila.hub.ActorLazyRef
import lila.mod.ModlogApi import lila.mod.ModlogApi
import lila.user.{ User, Context } import lila.user.{ User, Context }
@ -41,7 +41,7 @@ final class PostApi(
(indexer ! InsertPost(post)) >> (indexer ! InsertPost(post)) >>
(env.recent.invalidate inject post) >>- (env.recent.invalidate inject post) >>-
(ctx.userId ?? { userId (ctx.userId ?? { userId
relationActor ! MakeEntry( relationActor ! ShareEntry(
userId, userId,
ForumPost(userId, categ.id, topic.slug, topic.name, lastPageOf(topic withPost post), post.number) ForumPost(userId, categ.id, topic.slug, topic.name, lastPageOf(topic withPost post), post.number)
) )

View file

@ -60,7 +60,8 @@ package timeline {
implicit val forumPostFormat = Json.format[ForumPost] implicit val forumPostFormat = Json.format[ForumPost]
} }
case class MakeEntry(user: String, data: Atom) case class ShareEntry(user: String, data: Atom)
case class MakeEntry(users: List[String], data: Atom)
} }
package game { package game {

View file

@ -6,7 +6,7 @@ import akka.pattern.{ ask, pipe }
import actorApi._ import actorApi._
import lila.hub.actorApi.relation._ import lila.hub.actorApi.relation._
import lila.hub.actorApi.SendTos import lila.hub.actorApi.SendTos
import lila.hub.actorApi.timeline.MakeEntry import lila.hub.actorApi.timeline.{ MakeEntry, ShareEntry }
import lila.hub.ActorLazyRef import lila.hub.ActorLazyRef
private[relation] final class RelationActor( private[relation] final class RelationActor(
@ -18,11 +18,9 @@ private[relation] final class RelationActor(
def receive = { def receive = {
case MakeEntry(userId, data) getFriendIds(userId) foreach { ids case ShareEntry(userId, data) getFriendIds(userId) map { ids
ids foreach { id MakeEntry(ids.toList, data)
timelinePush ! MakeEntry(id, data) } pipeTo timelinePush.ref
}
}
// rarely called // rarely called
// return a list of usernames, followers, following and online // return a list of usernames, followers, following and online

View file

@ -3,7 +3,7 @@ package lila.relation
import lila.db.api._ import lila.db.api._
import lila.db.Implicits._ import lila.db.Implicits._
import lila.game.GameRepo import lila.game.GameRepo
import lila.hub.actorApi.timeline.{ MakeEntry, Follow FollowUser, FollowYou } import lila.hub.actorApi.timeline.{ MakeEntry, ShareEntry, Follow FollowUser, FollowYou }
import lila.hub.ActorLazyRef import lila.hub.ActorLazyRef
import lila.user.tube.userTube import lila.user.tube.userTube
import lila.user.{ User, UserRepo } import lila.user.{ User, UserRepo }
@ -35,8 +35,8 @@ final class RelationApi(
case Some(Follow) fufail("Already following") case Some(Follow) fufail("Already following")
case _ RelationRepo.follow(u1, u2) >> case _ RelationRepo.follow(u1, u2) >>
cached.invalidate(u1, u2) >>- cached.invalidate(u1, u2) >>-
(timelinePush ! MakeEntry(u2, FollowYou(u1))) >>- (timelinePush ! MakeEntry(List(u2), FollowYou(u1))) >>-
(relationActor ! MakeEntry(u1, FollowUser(u1, u2))) (relationActor ! ShareEntry(u1, FollowUser(u1, u2)))
} }
def block(u1: ID, u2: ID): Funit = def block(u1: ID, u2: ID): Funit =

View file

@ -5,7 +5,7 @@ import org.scala_tools.time.Imports._
import actorApi._ import actorApi._
import lila.db.api._ import lila.db.api._
import lila.hub.actorApi.forum.MakeTeam import lila.hub.actorApi.forum.MakeTeam
import lila.hub.actorApi.timeline.{ MakeEntry, TeamJoin, TeamCreate } import lila.hub.actorApi.timeline.{ ShareEntry, TeamJoin, TeamCreate }
import lila.hub.ActorLazyRef import lila.hub.ActorLazyRef
import lila.user.tube.userTube import lila.user.tube.userTube
import lila.user.{ User, Context } import lila.user.{ User, Context }
@ -37,7 +37,7 @@ final class TeamApi(
(cached.teamIds remove me.id) >>- (cached.teamIds remove me.id) >>-
(forum ! MakeTeam(team.id, team.name)) >>- (forum ! MakeTeam(team.id, team.name)) >>-
(indexer ! InsertTeam(team)) >>- (indexer ! InsertTeam(team)) >>-
(relationActor ! MakeEntry(me.id, TeamCreate(me.id, team.id))) inject team (relationActor ! ShareEntry(me.id, TeamCreate(me.id, team.id))) inject team
} }
def update(team: Team, edit: TeamEdit, me: User): Funit = edit.trim |> { e def update(team: Team, edit: TeamEdit, me: User): Funit = edit.trim |> { e
@ -114,7 +114,7 @@ final class TeamApi(
MemberRepo.add(team.id, userId) >> MemberRepo.add(team.id, userId) >>
TeamRepo.incMembers(team.id, +1) >> TeamRepo.incMembers(team.id, +1) >>
(cached.teamIds remove userId) >>- (cached.teamIds remove userId) >>-
(relationActor ! MakeEntry(userId, TeamJoin(userId, team.id))) (relationActor ! ShareEntry(userId, TeamJoin(userId, team.id)))
} }
} }

View file

@ -8,17 +8,14 @@ import lila.hub.actorApi.timeline._
import lila.hub.actorApi.timeline.atomFormat._ import lila.hub.actorApi.timeline.atomFormat._
case class Entry( case class Entry(
user: String, users: List[String],
typ: String, typ: String,
data: JsObject, data: JsObject,
date: DateTime) { date: DateTime) {
import Entry._ import Entry._
def similarTo(other: Entry) = def similarTo(other: Entry) = typ == other.typ && data == other.data
(user == other.user) &&
(typ == other.typ) &&
(data == other.data)
def decode: Option[Atom] = (typ match { def decode: Option[Atom] = (typ match {
case "follow" Json.fromJson[Follow](data) case "follow" Json.fromJson[Follow](data)
@ -31,14 +28,14 @@ case class Entry(
object Entry { object Entry {
private[timeline] def make(user: String, data: Atom): Option[Entry] = (data match { private[timeline] def make(users: List[String], data: Atom): Option[Entry] = (data match {
case d: Follow "follow" -> Json.toJson(d) case d: Follow "follow" -> Json.toJson(d)
case d: FollowYou "follow-you" -> Json.toJson(d) case d: FollowYou "follow-you" -> Json.toJson(d)
case d: TeamJoin "team-join" -> Json.toJson(d) case d: TeamJoin "team-join" -> Json.toJson(d)
case d: TeamCreate "team-create" -> Json.toJson(d) case d: TeamCreate "team-create" -> Json.toJson(d)
case d: ForumPost "forum-post" -> Json.toJson(d) case d: ForumPost "forum-post" -> Json.toJson(d)
}) match { }) match {
case (typ, json) json.asOpt[JsObject] map { new Entry(user, typ, _, DateTime.now) } case (typ, json) json.asOpt[JsObject] map { new Entry(users, typ, _, DateTime.now) }
} }
import lila.db.Tube import lila.db.Tube

View file

@ -17,20 +17,21 @@ private[timeline] final class Push(
renderer: lila.hub.ActorLazyRef) extends Actor { renderer: lila.hub.ActorLazyRef) extends Actor {
def receive = { def receive = {
case MakeEntry(user, data) makeEntry(user, data) foreach { entry case MakeEntry(users, data) makeEntry(users, data) >>-
lobbySocket.ref ! ReloadTimeline(user) (users foreach { u
} lobbySocket.ref ! ReloadTimeline(u)
})
} }
private def makeEntry(user: String, data: Atom): Fu[Entry] = private def makeEntry(users: List[String], data: Atom): Fu[Entry] =
Entry.make(user, data).fold( Entry.make(users, data).fold(
fufail[Entry]("[timeline] invalid entry data " + data) fufail[Entry]("[timeline] invalid entry data " + data)
) { entry ) { entry
$find(Json.obj("user" -> user, "date" -> $gt($date(DateTime.now - 1.hour)))) flatMap { entries $find(Json.obj("typ" -> entry.typ, "date" -> $gt($date(DateTime.now - 1.hour)))) flatMap { entries
entries exists (_ similarTo entry) fold ( entries exists (_ similarTo entry) fold (
fufail[Entry]("[timeline] a similar entry already exists"), fufail[Entry]("[timeline] a similar entry already exists"),
$insert(entry) inject entry $insert(entry) inject entry
) )
}
} }
}
} }

1
todo
View file

@ -71,7 +71,6 @@ takeback/enpassant glitch http://en.lichess.org/forum/lichess-feedback/i-found-a
show teams in user mini show teams in user mini
badges for top players in ELO and number of games badges for top players in ELO and number of games
use jquery.timeago everywhere use jquery.timeago everywhere
sort imports
DEPLOY p21 DEPLOY p21
---------- ----------