From 62013bc23d22319b65f6c6ec0442c37df8c6e1b6 Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Sat, 21 Sep 2024 17:41:49 +0200 Subject: [PATCH] try to fix ClientIn.Crowd equality in prod atm we can get duplicated events like ``` {"t":"crowd","d":{"nb":44}} {"t":"crowd","d":{"nb":44}} ``` but only in prod and I don't get it --- src/main/scala/actor/RoomActor.scala | 5 +++-- src/main/scala/ipc/ClientIn.scala | 9 +++++++-- src/main/scala/ipc/CrowdJson.scala | 6 +++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/main/scala/actor/RoomActor.scala b/src/main/scala/actor/RoomActor.scala index c182cea7..e620aca8 100644 --- a/src/main/scala/actor/RoomActor.scala +++ b/src/main/scala/actor/RoomActor.scala @@ -11,7 +11,7 @@ object RoomActor: case class State( room: RoomId, isTroll: IsTroll, - lastCrowd: ClientIn.Crowd = ClientIn.emptyCrowd + lastCrowd: ClientIn.Crowd = ClientIn.Crowd.empty ) def onStart( @@ -52,11 +52,12 @@ object RoomActor: case crowd: ClientIn.Crowd => val shouldSend = - if crowd == state.lastCrowd then false + if crowd.sameAs(state.lastCrowd) then false else if crowd.users != state.lastCrowd.users then true else if crowd.members > 1000 && crowd.members % 100 != 0 then false else if crowd.members > 100 && crowd.members % 10 != 0 then false else true + if shouldSend then deps.clientIn(crowd) Some(state.copy(lastCrowd = crowd)) -> None diff --git a/src/main/scala/ipc/ClientIn.scala b/src/main/scala/ipc/ClientIn.scala index 3e7a7fa2..7c05465e 100644 --- a/src/main/scala/ipc/ClientIn.scala +++ b/src/main/scala/ipc/ClientIn.scala @@ -68,9 +68,14 @@ object ClientIn: def payload(js: JsValue) = Payload(JsonString(Json.stringify(js))) def payload(tpe: String, js: JsonString) = Payload(JsonString(cliMsg(tpe, js))) - case class Crowd(doc: JsObject, members: Int, users: Set[User.Id]) extends ClientIn: + case class Crowd(doc: JsObject, members: Int, users: String) extends ClientIn: lazy val write = cliMsg("crowd", doc) - val emptyCrowd = Crowd(Json.obj(), 0, Set.empty) + inline def sameAs(that: Crowd) = members == that.members && users == that.users + + object Crowd: + def make(doc: JsObject, members: Int, userIds: Iterable[User.Id]) = + Crowd(doc, members, User.Id.raw(userIds.toList).sorted.mkString(",")) + val empty = make(Json.obj(), 0, Nil) case class LobbyPairing(fullId: Game.FullId) extends ClientIn: def write = diff --git a/src/main/scala/ipc/CrowdJson.scala b/src/main/scala/ipc/CrowdJson.scala index 14c4aa8d..eec53cb7 100644 --- a/src/main/scala/ipc/CrowdJson.scala +++ b/src/main/scala/ipc/CrowdJson.scala @@ -11,7 +11,7 @@ final class CrowdJson(inquirers: Inquirers, mongo: Mongo, lightUserApi: LightUse keepOnlyStudyMembers(crowd).map: users => crowd.copy(users = users, anons = 0) else Future.successful(crowd) - }.flatMap(spectatorsOf(_, crowd.users)).map(ClientIn.Crowd(_, crowd.members, crowd.users.toSet)) + }.flatMap(spectatorsOf(_, crowd.users)).map(ClientIn.Crowd.make(_, crowd.members, crowd.users)) def round(crowd: RoundCrowd.Output): Future[ClientIn.Crowd] = spectatorsOf( @@ -20,7 +20,7 @@ final class CrowdJson(inquirers: Inquirers, mongo: Mongo, lightUserApi: LightUse ), crowd.room.users ).map { spectators => - ClientIn.Crowd( + ClientIn.Crowd.make( Json .obj( "white" -> (crowd.players.white > 0), @@ -28,7 +28,7 @@ final class CrowdJson(inquirers: Inquirers, mongo: Mongo, lightUserApi: LightUse "watchers" -> spectators ), crowd.room.members, - Set.empty + Nil ) }