Deferred match listing/sorting

Hi there.

I’m not sure on how to implement this. Currently, with an RPC, I list the matches and send them back with JSON.
Then I implemented a sorting method, everything went well.
Lastly, I want to send out the matches, but only partially. During the first request, I’ll send 10 matches, then if on client side I click on the next button, the server will resume the list function, and then send out the 10 next matches.

Until now I’ve made a goroutine snippet waiting for request input, or timeout to exit the goroutine.

The goroutine

func listMatchGoroutine(ctx context.Context, nk runtime.NakamaModule, logger runtime.Logger, codeInput <-chan int, outMatches chan<- *api.Match) {
limit := 100 //Test only, need to be changed
authoritative := true
minSize := 0
maxSize := 19
label := “”

matches, _ := nk.MatchList(ctx, limit, authoritative, label, minSize, maxSize, "")

idx := 0

outMatches <- matches[idx]
idx = idx + 1

whileFlag := true

for whileFlag {
	select {
	case receivedCode := <-codeInput:
		if receivedCode == 1 {
			outMatches <- matches[idx] //SENDING OUT MATCH
			idx = idx + 1
		} else if receivedCode == 2 {
			whileFlag = false
	case <-time.After(time.Second * 10):
		whileFlag = false //TIMEOUT


Calling code

code := make(chan int)
	outM := make(chan *api.Match)

	go listMatchGoroutine(ctx, nk, logger, code, outM)
	receivedMatch := <-outM
	logger.Info("0:" + receivedMatch.GetMatchId())
	code <- 1
	receivedMatch = <-outM
	logger.Info("1:" + receivedMatch.GetMatchId())
	code <- 1
	receivedMatch = <-outM
	logger.Info("2:" + receivedMatch.GetMatchId())
	code <- 2

The problem now is that I can’t find a way to store the cannels out of the RPC, that I can access with another RPC to continue the listing.

Thanks in advance for the help, I hope I’ve been pretty clear.

If I understand correctly you’re trying to paginate match listing results, only return a small set to the client, and let the client request more?

In our experience we found it’s a better user experience to avoid that. I recommend the game UI provides enough filter options to narrow down the listing to a very small set of relevant matches, rather than page through a larger set of unwanted matches.

That said if you are sure this is the approach you need you can make the channels global variables in your Go code. If you do that then keep in mind that any user calling these functions would use those same variables.

We’ll also look into better ways to support this kind of match listing pagination in future releases. :+1:

Thanks for the quick reply.
You did understand well. I know this is not the best way of handling search, but it’s how is it designed (for the moment). The idea was to limit the data transfered to the player in one time.
You were talking about using filter options. I already do a pass with a lot of filters before preparing the list for the player.
I just forgot about global variables, it just worked well. Before posting the first message, I was thinking about a search table, to resume one if needed. The goroutine can destroy herself and the reference in the table after a certain time (30sec now) with the call of this.
<-time.After(time.Second * 30)

Thanks for the help

You should ideally avoid using the database as a cache like this, so if the global variable works as you intended keep using that. :+1:

Also keep an eye on Nakama future releases for a built-in way to paginate match listings!

1 Like