延續昨天補位的情境,我們今天要來實作一下補位的範例,同樣以官方提供的範例碼,由筆者加上註解與 debuf log 編譯完成後,放到 docker hub 上提供大家體驗看看,請使用這份 backfill.yaml 部署,裏面使用的是註解過後的 MMF。
同基本範例兩人成團的情境,本次若在第一時間不足兩人時,會產生一個補位的 backfill
這部分跟原本不同的地方在於,除了呼叫 matchfunction.QueryPool
以外, 還需要確認補問的部分,因此需要額外呼叫 matchfunction.QueryBackfillPool
,來帶入我們的配對邏輯 makeMatches
中。
func (s *matchFunctionService) Run(req *pb.RunRequest, stream pb.MatchFunction_RunServer) error {
log.Printf("Generating proposals for function %v", req.GetProfile().GetName())
var proposals []*pb.Match
profile := req.GetProfile()
pools := profile.GetPools()
for _, p := range pools {
tickets, err := matchfunction.QueryPool(stream.Context(), s.queryServiceClient, p)
if err != nil {
log.Printf("Failed to query tickets for the given pool, got %s", err.Error())
return err
}
backfills, err := matchfunction.QueryBackfillPool(stream.Context(), s.queryServiceClient, p)
if err != nil {
log.Printf("Failed to query backfills for the given pool, got %s", err.Error())
return err
}
for i := range backfills {
log.Printf("QueryBackfillPool get backfill_id: %s\n", backfills[i].Id)
}
matches, err := makeMatches(profile, p, tickets, backfills)
if err != nil {
log.Printf("Failed to generate matches, got %s", err.Error())
return err
}
proposals = append(proposals, matches...)
}
log.Printf("Streaming %v proposals to Open Match", len(proposals))
// Stream the generated proposals back to Open Match.
for _, proposal := range proposals {
if err := stream.Send(&pb.RunResponse{Proposal: proposal}); err != nil {
log.Printf("Failed to stream proposals to Open Match, got %s", err.Error())
return err
}
}
return nil
}
這裡是我們實踐補位邏輯的核心,在拿到想要配對的 tickets
與需要補位的數量 backfills
後,我們可以依據我們的配對人數,先將補位的部分處理好,如果補位後還有 tickets
則先配對成新遊戲,若有不足人數時(餘數),則在給予新的 backfill
。
func makeMatches(profile *pb.MatchProfile, pool *pb.Pool, tickets []*pb.Ticket, backfills []*pb.Backfill) ([]*pb.Match, error) {
var matches []*pb.Match
//先將 backfills 裡面的空位填滿
newMatches, remainingTickets, err := handleBackfills(profile, tickets, backfills, len(matches))
if err != nil {
return nil, err
}
//持續依照遊戲上線湊滿房間 create normal match
matches = append(matches, newMatches...)
newMatches, remainingTickets = makeFullMatches(profile, remainingTickets, len(matches))
matches = append(matches, newMatches...)
//餘數沒滿的情況 create match with backfill
if len(remainingTickets) > 0 {
match, err := makeMatchWithBackfill(profile, pool, remainingTickets, len(matches))
if err != nil {
return nil, err
}
matches = append(matches, match)
}
return matches, nil
}
可以透過在 MMF 加入的 debug log,來協助我們觀察其補位的過程