Add socket debug info

- Create a new runtime setting for socket debug info
- When setting is active, bad VersionCheck messages will send additional
  info. The client can then report this info together with their current
  version. Client reporting not implemented yet, but will be a simple
  GET or json post.
pull/5137/head
Isaac Levy 2019-05-22 19:39:12 -04:00
parent 74db64fb9f
commit e58a959bba
8 changed files with 39 additions and 8 deletions

View File

@ -19,7 +19,8 @@ object Dev extends LilaController {
Env.report.scoreThresholdSetting,
Env.api.cspEnabledSetting,
Env.streamer.alwaysFeaturedSetting,
Env.rating.ratingFactorsSetting
Env.rating.ratingFactorsSetting,
Env.socket.socketDebugSetting
)
def settings = Secure(_.Settings) { implicit ctx => me =>

View File

@ -391,7 +391,7 @@ lazy val tree = module("tree", Seq(common)).settings(
)
lazy val socket = module("socket", Seq(common, hub, memo, tree)).settings(
libraryDependencies ++= provided(play.api)
libraryDependencies ++= provided(play.api, reactivemongo.driver)
)
lazy val hub = module("hub", Seq(common)).settings(

View File

@ -36,7 +36,8 @@ final class Env(
evalCacheHandler: lila.evalCache.EvalCacheSocketHandler,
isBotSync: lila.common.LightUser.IsBotSync,
slackApi: lila.slack.SlackApi,
ratingFactors: () => lila.rating.RatingFactors
ratingFactors: () => lila.rating.RatingFactors,
val socketDebug: () => Boolean
) {
private val settings = new {
@ -278,6 +279,7 @@ object Env {
evalCacheHandler = lila.evalCache.Env.current.socketHandler,
isBotSync = lila.user.Env.current.lightUserApi.isBotSync,
slackApi = lila.slack.Env.current.api,
ratingFactors = lila.rating.Env.current.ratingFactorsSetting.get
ratingFactors = lila.rating.Env.current.ratingFactorsSetting.get,
socketDebug = lila.socket.Env.current.socketDebugSetting.get
)
}

View File

@ -27,6 +27,12 @@ private final class History(
events.headOption.fold(SocketVersion(0))(_.version)
}
def versionDebugString: String = {
s"${events.lastOption.fold(-1)(_.version.value)}:${
events.headOption.fold(-1)(_.version.value)
}"
}
def getEventsSince(v: SocketVersion, mon: Option[lila.mon.round.history.PlatformHistory]): EventResult = {
val version = getVersion
if (v > version) VersionTooHigh

View File

@ -210,13 +210,13 @@ private[round] final class RoundSocket(
case None =>
lila.mon.round.history(mobile).versionCheck.getEventsTooFar()
logger.info(s"Lost mobile:$mobile $version < ${history.getVersion} $gameId $member")
member push SocketTrouper.resyncMessage
member push SocketTrouper.resyncMsgWithDebug(s"sv(${history.versionDebugString}),cv($version)")
case Some(Nil) => // all good, nothing to do
case Some(evs) =>
lila.mon.round.history(mobile).getEventsDelta(evs.size)
lila.mon.round.history(mobile).versionCheck.lateClient()
logger.info(s"Late mobile:$mobile $version < ${evs.lastOption.??(_.version)} $gameId $member")
batchMsgs(member, evs) foreach member.push
batchMsgsDebug(member, evs, s"sv(${history.versionDebugString}),cv($version)") foreach member.push
}
case eventList: EventList => notify(eventList.events)
@ -297,6 +297,11 @@ private[round] final class RoundSocket(
case many => makeMessage("b", many map (_ jsFor member)).some
}
def batchMsgsDebug(member: Member, vevents: List[VersionedEvent], debug: => String) = {
if (Env.current.socketDebug()) makeMessageDebug("b", vevents map (_ jsFor member), debug).some
else batchMsgs(member, vevents)
}
def notifyOwner[A: Writes](color: Color, t: String, data: A) =
withOwnerOf(color) {
_ push makeMessage(t, data)

View File

@ -6,7 +6,8 @@ import com.typesafe.config.Config
import actorApi._
final class Env(
system: ActorSystem
system: ActorSystem,
settingStore: lila.memo.SettingStore.Builder
) {
import scala.concurrent.duration._
@ -18,11 +19,18 @@ final class Env(
private val userRegister = new UserRegister(system)
system.scheduler.schedule(5 seconds, 1 seconds) { population ! PopulationTell }
val socketDebugSetting = settingStore[Boolean](
"socketDebug",
default = false,
text = "Send extra debugging to websockets.".some
)
}
object Env {
lazy val current = "socket" boot new Env(
system = lila.common.PlayApp.system
system = lila.common.PlayApp.system,
settingStore = lila.memo.Env.current.settingStore
)
}

View File

@ -29,6 +29,11 @@ object Socket extends Socket {
}
private[socket] trait Socket {
def makeMessageDebug[A](t: String, data: A, debug: String)(implicit writes: Writes[A]): JsObject =
JsObject(new Map.Map3("t", JsString(t), "d", writes.writes(data), "debug", JsString(debug)))
def makeMessageDebug[A](t: String, debug: String): JsObject =
JsObject(new Map.Map2("t", JsString(t), "debug", JsString(debug)))
def makeMessage[A](t: String, data: A)(implicit writes: Writes[A]): JsObject =
JsObject(new Map.Map2("t", JsString(t), "d", writes.writes(data)))

View File

@ -178,6 +178,10 @@ object SocketTrouper extends Socket {
case class GetNbMembers(promise: Promise[Int])
val resyncMessage = makeMessage("resync")
def resyncMsgWithDebug(debug: => String) =
if (Env.current.socketDebugSetting.get) makeMessageDebug("resync", debug)
else resyncMessage
}
// Not managed by a TrouperMap