Day14 Example of Backfill

延续昨天补位的情境,我们今天要来实作一下补位的范例,同样以官方提供的范例码,由笔者加上注解与 debuf log 编译完成後,放到 docker hub 上提供大家体验看看,请使用这份 backfill.yaml 部署,里面使用的是注解过後的 MMF

范例解析

同基本范例两人成团的情境,本次若在第一时间不足两人时,会产生一个补位的 backfill

https://i.imgur.com/8Eeaeec.gif

QueryPool

这部分跟原本不同的地方在於,除了呼叫 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
}

makeMatches

这里是我们实践补位逻辑的核心,在拿到想要配对的 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,来协助我们观察其补位的过程
https://i.imgur.com/jVj014J.gif


<<:  用React刻自己的投资Dashboard Day7 - CORS与Proxy Server

>>:  Angular 深入浅出三十天:表单与测试 Day07 - 整合测试实作 - 登入系统 by Template Driven Forms

[Day 43] 心情随笔後台及前台(五) - 编辑心情随笔资料画面及动作

接下来要处理的是编辑的画面, 我们看一下昨天这个画面 右边有一个修改的按钮, 点下去之後就可以针对这...

[Day - 26] - Spring Swagger之我的SeaFood API 手册配制方法

Abstract 我们前面讲了许多Spring应用开发,但当我们开发好一套系统,势必要有一套API手...

绘制 3D 图片的工具|Spline

最近在看前端 3D 动画相关的技术,突然发现 Spline 这个设计工具,可以做出那种帅帅的3D&单...

[DAY18] Use Case 设计概念

缘起 Use Case 的职责是把业务逻辑封装,一个 Use Case 大致可以对应到一个 User...

Unity自主学习(十四):认识Unity介面(5)

昨天我们了解了游戏执行区以及场景编辑区中"Main Camera"物件对其的影响...