refactor historical socket messages to allow for member filtering
This commit is contained in:
parent
a0741fdc90
commit
4f827a8f3b
|
@ -18,7 +18,7 @@ final class Env(
|
|||
|
||||
lazy val preloader = new mashup.Preload(
|
||||
lobby = Env.lobby.lobby,
|
||||
history = Env.lobby.history,
|
||||
lobbyVersion = () => Env.lobby.history.version,
|
||||
featured = Env.tv.featured,
|
||||
relations = Env.relation.api,
|
||||
leaderboard = Env.user.cached.topRatingDay.apply,
|
||||
|
|
|
@ -24,7 +24,7 @@ import makeTimeout.large
|
|||
|
||||
final class Preload(
|
||||
lobby: ActorRef,
|
||||
history: History,
|
||||
lobbyVersion: () => Int,
|
||||
featured: Featured,
|
||||
relations: RelationApi,
|
||||
leaderboard: Int => Fu[List[User]],
|
||||
|
@ -56,7 +56,7 @@ final class Preload(
|
|||
streamsOnAir() map {
|
||||
case ((((((((((((hooks, posts), tours), feat), blocks), entries), lead), tWinners), puzzle), playing), filter), pools), streams) =>
|
||||
(Json.obj(
|
||||
"version" -> history.version,
|
||||
"version" -> lobbyVersion(),
|
||||
"pool" -> JsArray(hooks map (_.render)),
|
||||
"filter" -> filter.render,
|
||||
"blocks" -> blocks,
|
||||
|
|
|
@ -41,7 +41,7 @@ final class Env(
|
|||
lobby = lobby,
|
||||
socket = socket)
|
||||
|
||||
lazy val history = new History(ttl = MessageTtl)
|
||||
lazy val history = new History[actorApi.Messadata.type](ttl = MessageTtl)
|
||||
|
||||
{
|
||||
import scala.concurrent.duration._
|
||||
|
|
|
@ -11,8 +11,8 @@ import lila.game.GameRepo
|
|||
import lila.hub.actorApi.GetUids
|
||||
import lila.memo.ExpireSetMemo
|
||||
import lila.socket.actorApi.Broom
|
||||
import org.joda.time.DateTime
|
||||
import makeTimeout.short
|
||||
import org.joda.time.DateTime
|
||||
|
||||
private[lobby] final class Lobby(
|
||||
biter: Biter,
|
||||
|
|
|
@ -20,9 +20,9 @@ import lila.socket.{ SocketActor, History, Historical }
|
|||
import makeTimeout.short
|
||||
|
||||
private[lobby] final class Socket(
|
||||
val history: History,
|
||||
val history: History[Messadata.type],
|
||||
router: akka.actor.ActorSelection,
|
||||
uidTtl: Duration) extends SocketActor[Member](uidTtl) with Historical[Member] {
|
||||
uidTtl: Duration) extends SocketActor[Member](uidTtl) with Historical[Member, Messadata.type] {
|
||||
|
||||
context.system.lilaBus.subscribe(self, 'changeFeaturedGame, 'streams)
|
||||
|
||||
|
@ -46,9 +46,9 @@ private[lobby] final class Socket(
|
|||
|
||||
case ReloadTimeline(user) => sendTo(user, makeMessage("reload_timeline", JsNull))
|
||||
|
||||
case AddHook(hook) => notifyVersion("hook_add", hook.render)
|
||||
case AddHook(hook) => notifyVersion("hook_add", hook.render, Messadata)
|
||||
|
||||
case RemoveHook(hookId) => notifyVersion("hook_remove", hookId)
|
||||
case RemoveHook(hookId) => notifyVersion("hook_remove", hookId, Messadata)
|
||||
|
||||
case JoinHook(uid, hook, game, creatorColor) =>
|
||||
withMember(hook.uid)(notifyMember("redirect", Json.obj(
|
||||
|
@ -62,11 +62,13 @@ private[lobby] final class Socket(
|
|||
"cookie" -> AnonCookie.json(game, !creatorColor)
|
||||
).noNull))
|
||||
|
||||
case HookIds(ids) => notifyVersion("hook_list", ids)
|
||||
case HookIds(ids) => notifyVersion("hook_list", ids, Messadata)
|
||||
|
||||
case lila.hub.actorApi.StreamsOnAir(html) => notifyAll(makeMessage("streams", html))
|
||||
}
|
||||
|
||||
protected def shouldSkipMessageFor(message: Message, member: Member) = false
|
||||
|
||||
private def playerUrl(fullId: String) = s"/$fullId"
|
||||
|
||||
private def notifyTournaments(html: String) {
|
||||
|
|
|
@ -17,6 +17,8 @@ object Member {
|
|||
troll = user.??(_.troll))
|
||||
}
|
||||
|
||||
case object Messadata
|
||||
|
||||
case class Connected(enumerator: JsEnumerator, member: Member)
|
||||
case class WithHooks(op: Iterable[String] => Unit)
|
||||
case class AddHook(hook: Hook)
|
||||
|
|
|
@ -48,7 +48,7 @@ final class Env(
|
|||
setup = setupRepo byId id getOrElse {
|
||||
throw new IllegalArgumentException(s"Can't create pool for id $id")
|
||||
},
|
||||
history = new History(ttl = HistoryMessageTtl),
|
||||
history = new History[actorApi.Messadata](ttl = HistoryMessageTtl),
|
||||
uidTimeout = UidTimeout,
|
||||
lightUser = lightUser,
|
||||
isOnline = isOnline,
|
||||
|
|
|
@ -18,12 +18,12 @@ import lila.user.{ User, UserRepo }
|
|||
|
||||
private[pool] final class PoolActor(
|
||||
setup: PoolSetup,
|
||||
val history: History,
|
||||
val history: History[Messadata],
|
||||
lightUser: String => Option[LightUser],
|
||||
isOnline: String => Boolean,
|
||||
renderer: ActorSelection,
|
||||
joiner: Joiner,
|
||||
uidTimeout: Duration) extends SocketActor[Member](uidTimeout) with Historical[Member] {
|
||||
uidTimeout: Duration) extends SocketActor[Member](uidTimeout) with Historical[Member, Messadata] {
|
||||
|
||||
private var pool = Pool(setup, Nil, Nil, DateTime.now plusSeconds 5)
|
||||
|
||||
|
@ -154,7 +154,7 @@ private[pool] final class PoolActor(
|
|||
|
||||
case lila.chat.actorApi.ChatLine(_, line) => line match {
|
||||
case line: lila.chat.UserLine =>
|
||||
notifyVersionTrollable("message", lila.chat.Line toJson line, troll = line.troll)
|
||||
notifyVersion("message", lila.chat.Line toJson line, Messadata(line.troll))
|
||||
case _ =>
|
||||
}
|
||||
|
||||
|
@ -176,22 +176,20 @@ private[pool] final class PoolActor(
|
|||
pool = pool withoutUserId userId
|
||||
}
|
||||
|
||||
protected def shouldSkipMessageFor(message: Message, member: Member) =
|
||||
message.metadata.trollish && !member.troll
|
||||
|
||||
val crowdNotifier =
|
||||
context.system.actorOf(Props(new Debouncer(1.seconds, (ms: Iterable[Member]) => {
|
||||
val (anons, users) = ms.map(_.userId flatMap lightUser).foldLeft(0 -> List[LightUser]()) {
|
||||
case ((anons, users), Some(user)) => anons -> (user :: users)
|
||||
case ((anons, users), None) => (anons + 1) -> users
|
||||
}
|
||||
notifyVersion("crowd", showSpectators(users, anons))
|
||||
notifyVersion("crowd", showSpectators(users, anons), Messadata())
|
||||
})))
|
||||
|
||||
val reloadNotifier =
|
||||
context.system.actorOf(Props(new Debouncer(1.seconds, (_: Debouncer.Nothing) => {
|
||||
notifyAll(makeMessage("reload"))
|
||||
})))
|
||||
|
||||
def notifyVersionTrollable[A: Writes](t: String, data: A, troll: Boolean) {
|
||||
val vmsg = history.+=(makeMessage(t, data), troll)
|
||||
members.values.foreach(sendMessage(vmsg))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ private[pool] object Member {
|
|||
troll = user.??(_.troll))
|
||||
}
|
||||
|
||||
private[pool] case class Messadata(trollish: Boolean = false)
|
||||
|
||||
private[pool] case class Join(
|
||||
uid: String,
|
||||
user: Option[User],
|
||||
|
|
|
@ -2,23 +2,27 @@ package lila.socket
|
|||
|
||||
import play.api.libs.json._
|
||||
|
||||
trait Historical[M <: SocketMember] { self: SocketActor[M] =>
|
||||
trait Historical[M <: SocketMember, Metadata] { self: SocketActor[M] =>
|
||||
|
||||
val history: History
|
||||
val history: History[Metadata]
|
||||
|
||||
def notifyVersion[A: Writes](t: String, data: A, troll: Boolean = false) {
|
||||
val vmsg = history.+=(makeMessage(t, data), troll)
|
||||
protected type Message = History.Message[Metadata]
|
||||
|
||||
protected def shouldSkipMessageFor(message: Message, member: M): Boolean
|
||||
|
||||
def notifyVersion[A: Writes](t: String, data: A, metadata: Metadata) {
|
||||
val vmsg = history.+=(makeMessage(t, data), metadata)
|
||||
val send = sendMessage(vmsg) _
|
||||
members.values.foreach(send)
|
||||
}
|
||||
|
||||
def sendMessage(message: History.Message)(member: M) {
|
||||
def sendMessage(message:Message)(member: M) {
|
||||
member.channel push {
|
||||
if (message.troll && !member.troll) message.skipMsg
|
||||
if (shouldSkipMessageFor(message, member)) message.skipMsg
|
||||
else message.fullMsg
|
||||
}
|
||||
}
|
||||
def sendMessage(member: M)(message: History.Message) {
|
||||
def sendMessage(member: M)(message: Message) {
|
||||
sendMessage(message)(member)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@ import play.api.libs.json._
|
|||
import actorApi._
|
||||
import lila.memo
|
||||
|
||||
final class History(ttl: Duration) {
|
||||
final class History[Metadata](ttl: Duration) {
|
||||
|
||||
import History._
|
||||
type Message = History.Message[Metadata]
|
||||
|
||||
private var privateVersion = 0
|
||||
private val messages = memo.Builder.expiry[Int, Message](ttl)
|
||||
|
@ -25,9 +25,9 @@ final class History(ttl: Duration) {
|
|||
|
||||
private def message(v: Int) = Option(messages getIfPresent v)
|
||||
|
||||
def +=(payload: JsObject, troll: Boolean): Message = {
|
||||
def +=(payload: JsObject, metadata: Metadata): Message = {
|
||||
privateVersion = privateVersion + 1
|
||||
val vmsg = Message(payload, privateVersion, troll)
|
||||
val vmsg = History.Message(payload, privateVersion, metadata)
|
||||
messages.put(privateVersion, vmsg)
|
||||
vmsg
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ final class History(ttl: Duration) {
|
|||
|
||||
object History {
|
||||
|
||||
case class Message(payload: JsObject, version: Int, troll: Boolean = false) {
|
||||
case class Message[Metadata](payload: JsObject, version: Int, metadata: Metadata) {
|
||||
|
||||
lazy val fullMsg = payload + ("v" -> JsNumber(version))
|
||||
|
||||
|
|
|
@ -16,10 +16,10 @@ import lila.socket.{ SocketActor, History, Historical }
|
|||
|
||||
private[tournament] final class Socket(
|
||||
tournamentId: String,
|
||||
val history: History,
|
||||
val history: History[Messadata],
|
||||
lightUser: String => Option[LightUser],
|
||||
uidTimeout: Duration,
|
||||
socketTimeout: Duration) extends SocketActor[Member](uidTimeout) with Historical[Member] {
|
||||
socketTimeout: Duration) extends SocketActor[Member](uidTimeout) with Historical[Member, Messadata] {
|
||||
|
||||
val joiningMemo = new ExpireSetMemo(uidTimeout)
|
||||
|
||||
|
@ -37,9 +37,9 @@ private[tournament] final class Socket(
|
|||
|
||||
case Reload => reloadNotifier ! Debouncer.Nothing
|
||||
|
||||
case Start => notifyVersion("start", JsNull)
|
||||
case Start => notifyVersion("start", JsNull, Messadata())
|
||||
|
||||
case ReloadPage => notifyVersion("reloadPage", JsNull)
|
||||
case ReloadPage => notifyVersion("reloadPage", JsNull, Messadata())
|
||||
|
||||
case PingVersion(uid, v) => {
|
||||
ping(uid)
|
||||
|
@ -56,7 +56,7 @@ private[tournament] final class Socket(
|
|||
|
||||
case lila.chat.actorApi.ChatLine(_, line) => line match {
|
||||
case line: lila.chat.UserLine =>
|
||||
notifyVersionTrollable("message", lila.chat.Line toJson line, troll = line.troll)
|
||||
notifyVersion("message", lila.chat.Line toJson line, Messadata(line.troll))
|
||||
case _ =>
|
||||
}
|
||||
|
||||
|
@ -78,22 +78,20 @@ private[tournament] final class Socket(
|
|||
|
||||
override def userIds = (super.userIds ++ joiningMemo.keys).toList.distinct
|
||||
|
||||
protected def shouldSkipMessageFor(message: Message, member: Member) =
|
||||
message.metadata.trollish && !member.troll
|
||||
|
||||
val crowdNotifier =
|
||||
context.system.actorOf(Props(new Debouncer(1.seconds, (ms: Iterable[Member]) => {
|
||||
val (anons, users) = members.values.map(_.userId flatMap lightUser).foldLeft(0 -> List[LightUser]()) {
|
||||
case ((anons, users), Some(user)) => anons -> (user :: users)
|
||||
case ((anons, users), None) => (anons + 1) -> users
|
||||
}
|
||||
notifyVersion("crowd", showSpectators(users, anons))
|
||||
notifyVersion("crowd", showSpectators(users, anons), Messadata())
|
||||
})))
|
||||
|
||||
val reloadNotifier =
|
||||
context.system.actorOf(Props(new Debouncer(1.seconds, (_: Debouncer.Nothing) => {
|
||||
notifyAll(makeMessage("reload"))
|
||||
})))
|
||||
|
||||
def notifyVersionTrollable[A: Writes](t: String, data: A, troll: Boolean) {
|
||||
val vmsg = history.+=(makeMessage(t, data), troll)
|
||||
members.values.foreach(sendMessage(vmsg))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,29 +5,31 @@ import lila.game.Game
|
|||
import lila.socket.SocketMember
|
||||
import lila.user.User
|
||||
|
||||
case class Member(
|
||||
private[tournament] case class Member(
|
||||
channel: JsChannel,
|
||||
userId: Option[String],
|
||||
troll: Boolean) extends SocketMember
|
||||
|
||||
object Member {
|
||||
private[tournament] object Member {
|
||||
def apply(channel: JsChannel, user: Option[User]): Member = Member(
|
||||
channel = channel,
|
||||
userId = user map (_.id),
|
||||
troll = user.??(_.troll))
|
||||
}
|
||||
|
||||
case class Join(
|
||||
private[tournament] case class Messadata(trollish: Boolean = false)
|
||||
|
||||
private[tournament] case class Join(
|
||||
uid: String,
|
||||
user: Option[User],
|
||||
version: Int)
|
||||
case class Talk(tourId: String, u: String, t: String, troll: Boolean)
|
||||
case object Start
|
||||
case object Reload
|
||||
case object ReloadPage
|
||||
case class StartGame(game: Game)
|
||||
case class Joining(userId: String)
|
||||
case class Connected(enumerator: JsEnumerator, member: Member)
|
||||
private[tournament] case class Talk(tourId: String, u: String, t: String, troll: Boolean)
|
||||
private[tournament] case object Start
|
||||
private[tournament] case object Reload
|
||||
private[tournament] case object ReloadPage
|
||||
private[tournament] case class StartGame(game: Game)
|
||||
private[tournament] case class Joining(userId: String)
|
||||
private[tournament] case class Connected(enumerator: JsEnumerator, member: Member)
|
||||
|
||||
// organizer
|
||||
private[tournament] case object AllCreatedTournaments
|
||||
|
|
Loading…
Reference in a new issue