open-match icon indicating copy to clipboard operation
open-match copied to clipboard

Best practices for local development

Open castaneai opened this issue 5 years ago • 4 comments

Hi, I'm currently developing matchmaking with open-match.

Mainly in MMFs that we developers create on our own, we need short iterations to develop games quickly. There are solutions like minikube for local development, but it's not suitable for development that requires frequent code changes. (Related to #163) We also tried skaffold, but it was difficult to take advantage of debugging with delve, which requires a lot of special preparation.

So we have a few questions.

  • What kind of environment do you envision for developing (or debugging) game specific logic like MMF, how do you develop MMF?

  • Are there any best practices for testing MMF without Kubernetes and using lightweight tools like go test?

castaneai avatar Sep 18 '20 13:09 castaneai

@castaneai - I'm curious - are you writing unit tests for your MMF functions already?

markmandel avatar Sep 18 '20 16:09 markmandel

Yes, I'm testing MMF by creating a mock QueryServiceClient as follows.

type mockOM struct {
	pools map[string][]*pb.Ticket
	mu    sync.RWMutex
}

func (q *mockOM) CreateTicket(poolName string, ticket *pb.Ticket) {
	q.mu.Lock()
	defer q.mu.Unlock()

	if _, ok := q.pools[poolName]; !ok {
		q.pools[poolName] = nil
	}
	q.pools[poolName] = append(q.pools[poolName], ticket)
}


func (q *mockOM) QueryTickets(ctx context.Context, in *pb.QueryTicketsRequest, opts ...grpc.CallOption) (pb.QueryService_QueryTicketsClient, error) {
	q.mu.RLock()
	defer q.mu.RUnlock()

	tickets, ok := q.pools[in.Pool.Name]
	if !ok {
		return &mockQueryServiceClientStream{tickets: nil}, nil
	}
	return &mockQueryServiceClientStream{tickets: tickets}, nil
}

type mockQueryServiceClientStream struct {
	tickets []*pb.Ticket
	grpc.ClientStream
}

func (s *mockQueryServiceClientStream) Recv() (*pb.QueryTicketsResponse, error) {
	tickets := s.tickets
	if len(tickets) > 0 {
		s.tickets = nil
		return &pb.QueryTicketsResponse{Tickets: tickets}, nil
	}
	return nil, io.EOF
}

This method is working well for us, but I would like to know if there is a better way provided.

castaneai avatar Sep 19 '20 02:09 castaneai

@castaneai - I like the thought going into testing MMFs which is something I also have been thinking about lately.

I've been learning more about Cloud Code which allows you to debug cloud native apps (locally as well). I thought Open Match would be a good candidate for it. Here is some docs for reference. It works with VSCode and IntelliJ.

Testing locally with Cloud Code seems to be ideal for your use case since you can make code changes and run locally. You do have to set up either Docker Desktop or MiniKube but the great thing is when watch mode is enabled it will redeploy automatically after code changes are made which seems to be a key development approach for writing/debugging MMFs for you.

syntxerror avatar Sep 21 '20 16:09 syntxerror

@jonfoust Thank you.

I also think it's important to reset the backend state for test independence.

I run the FLUSHALL command to initialize om-Redis before each test. What do you think about this approach?

castaneai avatar Oct 06 '20 07:10 castaneai

Closing due to staleness

syntxerror avatar Sep 26 '22 15:09 syntxerror