Game Queue
The game has a queue service that stores all the Players
that are waiting to be in a match, and the ongoing match in a game
hash. They're saved on a Redis
service.
The queue starts when the server receives a JoinQueue
event from the Client.
case client := <-pool.JoinQueue:
redis.AddPlayerToQueue(client)
firstPlayer, secondPlayer, created := redis.CreateGame()
...
break
After receiving that event, we call the redis
package to enqueue the player.
func AddPlayerToQueue(player *dto.Player) {
val, err := json.Marshal(*player)
if err != nil {
log.Printf("Error trying to save player? %v", err)
return
}
err = rdb.RPush(ctx, "players", val).Err()
if err != nil {
log.Printf("Error trying to save player: %v", err)
}
}
We push the player information to a Redis List
and, after that has been pushed, then we try to create the game
hash.
case client := <-pool.JoinQueue:
...
firstPlayer, secondPlayer, created := redis.CreateGame()
...
break
package redis
func CreateGame() (dto.Player, dto.Player, bool) {
encodedGame, err := rdb.HGetAll(ctx, "game").Result()
if err != nil {
log.Printf("Error trying to get dto Hash: %v", err)
return dto.Player{}, dto.Player{}, false
}
firstPlayer, secondPlayer, unavailable := getPlayersToMatch()
if unavailable {
return dto.Player{}, dto.Player{}, false
}
_, errorParsing := dto.ParseGameFromMap(encodedGame)
if errorParsing != nil {
encodedFirstPlayer, _ := dto.ConvertPlayerToJson(&firstPlayer)
encodedSecondPlayer, _ := dto.ConvertPlayerToJson(&secondPlayer)
err = rdb.HSet(ctx, "game", map[string]interface{}{
"player1": encodedFirstPlayer,
"player2": encodedSecondPlayer,
}).Err()
if err != nil {
log.Printf("Error creating game: %v", err)
return dto.Player{}, dto.Player{}, false
}
return firstPlayer, secondPlayer, true
}
return dto.Player{}, dto.Player{}, false
}
Here, we first try to fetch a game
hash from the Redis
instance. If there's a hash
, it means that a match is on progress. Also, we try to get the players to create a match
firstPlayer, secondPlayer, unavailable := getPlayersToMatch()
The unavailable
variable will be true
if there's one of those players missing or if there was an error trying to fetch them from the Redis
instance
We try to "parse" the hash
_, errorParsing := dto.ParseGameFromMap(encodedGame)
In this case, if there's an error (Meaning, either there's no hash or one of the two players does not exists in that hash), then we could create a new game
Last updated