mirror of
https://github.com/nolen777/eagle0.git
synced 2026-07-28 20:55:44 +00:00
Instrument Shardok command latency in Eagle (#8763)
This commit is contained in:
@@ -255,6 +255,31 @@ class EagleShardokClientCommandReceivedEvent extends Event {
|
||||
var requestBytes: Int = 0
|
||||
}
|
||||
|
||||
@Name("net.eagle0.eagle.ShardokPlacementCommandsReceived")
|
||||
@Label("Eagle Shardok Placement Commands Received")
|
||||
@Category(Array("Eagle0", "Shardok"))
|
||||
@Enabled(true)
|
||||
@StackTrace(false)
|
||||
class EagleShardokPlacementCommandsReceivedEvent extends Event {
|
||||
@Label("Eagle Game ID")
|
||||
var eagleGameId: String = ""
|
||||
|
||||
@Label("Shardok Game ID")
|
||||
var shardokGameId: String = ""
|
||||
|
||||
@Label("Player ID")
|
||||
var playerId: Int = 0
|
||||
|
||||
@Label("Token")
|
||||
var token: Long = 0L
|
||||
|
||||
@Label("Placement Count")
|
||||
var placementCount: Int = 0
|
||||
|
||||
@Label("Request Bytes")
|
||||
var requestBytes: Int = 0
|
||||
}
|
||||
|
||||
object JfrEvents {
|
||||
private val usePostgresQueryEvents = new ThreadLocal[Boolean]()
|
||||
|
||||
@@ -483,4 +508,24 @@ object JfrEvents {
|
||||
event.commit()
|
||||
}
|
||||
}
|
||||
|
||||
def shardokPlacementCommandsReceived(
|
||||
eagleGameId: => String,
|
||||
shardokGameId: => String,
|
||||
playerId: Int,
|
||||
token: Long,
|
||||
placementCount: Int,
|
||||
requestBytes: => Int
|
||||
): Unit = {
|
||||
val event = new EagleShardokPlacementCommandsReceivedEvent()
|
||||
if event.isEnabled then {
|
||||
event.eagleGameId = eagleGameId
|
||||
event.shardokGameId = shardokGameId
|
||||
event.playerId = playerId
|
||||
event.token = token
|
||||
event.placementCount = placementCount
|
||||
event.requestBytes = requestBytes
|
||||
event.commit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ class EagleServiceImpl(
|
||||
request: PostCommandRequest
|
||||
): Future[PostCommandResponse] = {
|
||||
request.command match {
|
||||
case ShardokCommand(shardokGameId, playerId, shardokToken, index, roll, _) =>
|
||||
case ShardokCommand(shardokGameId, playerId, shardokToken, index, roll, _) =>
|
||||
JfrEvents.shardokClientCommandReceived(
|
||||
eagleGameId = request.gameId.toHexString,
|
||||
shardokGameId = shardokGameId,
|
||||
@@ -127,7 +127,16 @@ class EagleServiceImpl(
|
||||
roll = roll,
|
||||
requestBytes = request.serializedSize
|
||||
)
|
||||
case _ => ()
|
||||
case ShardokPlacementCommands(shardokGameId, playerId, commands, shardokToken, _) =>
|
||||
JfrEvents.shardokPlacementCommandsReceived(
|
||||
eagleGameId = request.gameId.toHexString,
|
||||
shardokGameId = shardokGameId,
|
||||
playerId = playerId,
|
||||
token = shardokToken,
|
||||
placementCount = commands.size,
|
||||
requestBytes = request.serializedSize
|
||||
)
|
||||
case _ => ()
|
||||
}
|
||||
|
||||
lockAndDoWithUserId { uid =>
|
||||
|
||||
@@ -1942,29 +1942,46 @@ class GamesManager(
|
||||
roll: Option[Int]
|
||||
): Unit = {
|
||||
requireLoadedGame(eagleGameId)
|
||||
this.synchronized {
|
||||
val eagleFactionId = requireShardokCommandAllowed(
|
||||
userId = userId,
|
||||
eagleGameId = eagleGameId,
|
||||
shardokGameId = shardokGameId,
|
||||
shardokPlayerId = shardokPlayerId
|
||||
)
|
||||
SimpleTimedLogger
|
||||
.fileLogger(eagleGameId, "timings")
|
||||
.withStopwatch("postShardokCommand") {
|
||||
shardokClient.postCommand(
|
||||
eagleGameId = eagleGameId,
|
||||
shardokGameId = shardokGameId,
|
||||
shardokPlayerId = shardokPlayerId,
|
||||
token = shardokToken,
|
||||
index = index,
|
||||
roll = roll,
|
||||
eagleFactionId = eagleFactionId
|
||||
)
|
||||
JfrEvents.postActionPhase(eagleGameId.toHexString, "gamesManager.postShardokCommand.total") { totalEvent =>
|
||||
totalEvent.itemCount = 1
|
||||
this.synchronized {
|
||||
JfrEvents.postActionPhase(eagleGameId.toHexString, "gamesManager.postShardokCommand.criticalSection") {
|
||||
criticalSectionEvent =>
|
||||
criticalSectionEvent.itemCount = 1
|
||||
val eagleFactionId = requireShardokCommandAllowed(
|
||||
userId = userId,
|
||||
eagleGameId = eagleGameId,
|
||||
shardokGameId = shardokGameId,
|
||||
shardokPlayerId = shardokPlayerId
|
||||
)
|
||||
criticalSectionEvent.factionId = eagleFactionId
|
||||
SimpleTimedLogger
|
||||
.fileLogger(eagleGameId, "timings")
|
||||
.withStopwatch("postShardokCommand") {
|
||||
JfrEvents.postActionPhase(
|
||||
eagleGameId.toHexString,
|
||||
"gamesManager.postShardokCommand.rpc",
|
||||
factionId = eagleFactionId
|
||||
) { rpcEvent =>
|
||||
rpcEvent.itemCount = 1
|
||||
shardokClient.postCommand(
|
||||
eagleGameId = eagleGameId,
|
||||
shardokGameId = shardokGameId,
|
||||
shardokPlayerId = shardokPlayerId,
|
||||
token = shardokToken,
|
||||
index = index,
|
||||
roll = roll,
|
||||
eagleFactionId = eagleFactionId
|
||||
)
|
||||
}
|
||||
}
|
||||
// Record last played time for this user
|
||||
updateLastPlayed(eagleGameId, userId)
|
||||
save()
|
||||
totalEvent.factionId = eagleFactionId
|
||||
()
|
||||
}
|
||||
// Record last played time for this user
|
||||
updateLastPlayed(eagleGameId, userId)
|
||||
save()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1977,23 +1994,40 @@ class GamesManager(
|
||||
shardokToken: Long
|
||||
): Unit = {
|
||||
requireLoadedGame(eagleGameId)
|
||||
this.synchronized {
|
||||
val eagleFactionId = requireShardokCommandAllowed(
|
||||
userId = userId,
|
||||
eagleGameId = eagleGameId,
|
||||
shardokGameId = shardokGameId,
|
||||
shardokPlayerId = shardokPlayerId
|
||||
)
|
||||
shardokClient.postPlacementCommands(
|
||||
eagleGameId = eagleGameId,
|
||||
shardokGameId = shardokGameId,
|
||||
shardokPlayerId = shardokPlayerId,
|
||||
placementCommands = placementCommands.map { pc =>
|
||||
PlacementCommand(unitId = pc.unitId, row = pc.row, column = pc.column)
|
||||
},
|
||||
token = shardokToken,
|
||||
eagleFactionId = eagleFactionId
|
||||
)
|
||||
JfrEvents.postActionPhase(eagleGameId.toHexString, "gamesManager.postPlacementCommands.total") { totalEvent =>
|
||||
totalEvent.itemCount = placementCommands.size
|
||||
this.synchronized {
|
||||
JfrEvents.postActionPhase(eagleGameId.toHexString, "gamesManager.postPlacementCommands.criticalSection") {
|
||||
criticalSectionEvent =>
|
||||
criticalSectionEvent.itemCount = placementCommands.size
|
||||
val eagleFactionId = requireShardokCommandAllowed(
|
||||
userId = userId,
|
||||
eagleGameId = eagleGameId,
|
||||
shardokGameId = shardokGameId,
|
||||
shardokPlayerId = shardokPlayerId
|
||||
)
|
||||
criticalSectionEvent.factionId = eagleFactionId
|
||||
JfrEvents.postActionPhase(
|
||||
eagleGameId.toHexString,
|
||||
"gamesManager.postPlacementCommands.rpc",
|
||||
factionId = eagleFactionId
|
||||
) { rpcEvent =>
|
||||
rpcEvent.itemCount = placementCommands.size
|
||||
shardokClient.postPlacementCommands(
|
||||
eagleGameId = eagleGameId,
|
||||
shardokGameId = shardokGameId,
|
||||
shardokPlayerId = shardokPlayerId,
|
||||
placementCommands = placementCommands.map { pc =>
|
||||
PlacementCommand(unitId = pc.unitId, row = pc.row, column = pc.column)
|
||||
},
|
||||
token = shardokToken,
|
||||
eagleFactionId = eagleFactionId
|
||||
)
|
||||
}
|
||||
totalEvent.factionId = eagleFactionId
|
||||
()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -102,6 +102,43 @@ class JfrEventsTest extends AnyFlatSpec with Matchers {
|
||||
}
|
||||
}
|
||||
|
||||
"shardokPlacementCommandsReceived" should "record placement command arrival metadata" in {
|
||||
val recordingPath = Files.createTempFile("eagle-shardok-placement-commands", ".jfr")
|
||||
val recording = new Recording()
|
||||
try {
|
||||
recording.enable("net.eagle0.eagle.ShardokPlacementCommandsReceived")
|
||||
recording.start()
|
||||
|
||||
JfrEvents.shardokPlacementCommandsReceived(
|
||||
eagleGameId = "eagle-game-123",
|
||||
shardokGameId = "shardok-game-456",
|
||||
playerId = 7,
|
||||
token = 42L,
|
||||
placementCount = 6,
|
||||
requestBytes = 12345
|
||||
)
|
||||
|
||||
recording.stop()
|
||||
recording.dump(recordingPath)
|
||||
|
||||
val event = RecordingFile
|
||||
.readAllEvents(recordingPath)
|
||||
.asScala
|
||||
.find(_.getEventType.getName == "net.eagle0.eagle.ShardokPlacementCommandsReceived")
|
||||
.getOrElse(fail("ShardokPlacementCommandsReceived event was not recorded"))
|
||||
event.getString("eagleGameId") shouldBe "eagle-game-123"
|
||||
event.getString("shardokGameId") shouldBe "shardok-game-456"
|
||||
event.getInt("playerId") shouldBe 7
|
||||
event.getLong("token") shouldBe 42L
|
||||
event.getInt("placementCount") shouldBe 6
|
||||
event.getInt("requestBytes") shouldBe 12345
|
||||
event.getStackTrace shouldBe null
|
||||
} finally {
|
||||
recording.close()
|
||||
Files.deleteIfExists(recordingPath): Unit
|
||||
}
|
||||
}
|
||||
|
||||
"historyAppendPhase" should "record phase metadata and counts" in {
|
||||
val recordingPath = Files.createTempFile("eagle-history-append-phase", ".jfr")
|
||||
val recording = new Recording()
|
||||
|
||||
Reference in New Issue
Block a user