From 1f0a170bfb05adf27c1ee92bdb0b7fb536712950 Mon Sep 17 00:00:00 2001 From: Andrei Mihu Date: Thu, 17 Mar 2022 14:01:42 +0000 Subject: [PATCH] Ensure the matchmaker always correctly prefers matches closer to the maximum count. (#809) --- CHANGELOG.md | 2 ++ server/match_registry_test.go | 4 ++-- server/matchmaker.go | 23 ++++++++++++++++++++--- server/runtime_javascript_test.go | 5 +++-- 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ef4834f3..7e37e397b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,8 @@ The format is based on [keep a changelog](http://keepachangelog.com) and this pr - Fix incorrect link device behaviour in JavaScript runtime. - Fix JS runtime multi-update execution consistency when part of the operation fails. - Fix handling of wallet ledger lookups with no limit during account exports. +- Ensure maximum count is accounted for in matchmaker mutual match checks. +- Ensure the matchmaker always correctly prefers matches closer to the maximum count. ## [3.10.0] - 2021-12-16 ### Added diff --git a/server/match_registry_test.go b/server/match_registry_test.go index 27198bfd0..945ba46f7 100644 --- a/server/match_registry_test.go +++ b/server/match_registry_test.go @@ -19,14 +19,14 @@ import ( "context" "encoding/gob" "fmt" - "go.uber.org/atomic" - "go.uber.org/zap" "strings" "testing" "github.com/blugelabs/bluge" "github.com/gofrs/uuid" "github.com/heroiclabs/nakama-common/runtime" + "go.uber.org/atomic" + "go.uber.org/zap" "google.golang.org/protobuf/types/known/wrapperspb" ) diff --git a/server/matchmaker.go b/server/matchmaker.go index 19a7cc1f3..a33e1a2bd 100644 --- a/server/matchmaker.go +++ b/server/matchmaker.go @@ -260,7 +260,7 @@ func (m *LocalMatchmaker) process(batch *index.Batch) { // Form possible combinations, in case multiple matches might be suitable. entryCombos := make([][]*MatchmakerEntry, 0, 5) - for _, hit := range blugeMatches.Hits { + for hitCounter, hit := range blugeMatches.Hits { if hit.ID == ticket { // Skip the current ticket. continue @@ -278,7 +278,7 @@ func (m *LocalMatchmaker) process(batch *index.Batch) { m.logger.Error("error validating mutual match", zap.Error(err)) continue } else if !outerMutualMatch { - // this search hit is not a mutual match with the outer ticket + // This search hit is not a mutual match with the outer ticket. continue } @@ -365,7 +365,12 @@ func (m *LocalMatchmaker) process(batch *index.Batch) { foundComboIdx = len(entryCombos) - 1 } - if l := len(foundCombo) + index.Count; l == index.MaxCount || (lastInterval && l >= index.MinCount && l <= index.MaxCount) { + // The combo is considered match-worthy if either the max count has been satisfied, or ALL of these conditions are met: + // * It is the last interval for this active index. + // * The combo at least satisfies the min count. + // * The combo does not exceed the max count. + // * There are no further hits that may further fill the found combo, so we get as close as possible to the max count. + if l := len(foundCombo) + index.Count; l == index.MaxCount || (lastInterval && l >= index.MinCount && l <= index.MaxCount && hitCounter >= len(blugeMatches.Hits)-1) { // Check that the minimum count that satisfies the current index is also good enough for all matched entries. var minCountFailed bool for _, e := range foundCombo { @@ -378,6 +383,18 @@ func (m *LocalMatchmaker) process(batch *index.Batch) { continue } + // Check that the maximum count that satisfies the current index is also good enough for all matched entries. + var maxCountFailed bool + for _, e := range foundCombo { + if foundIndex, ok := m.indexes[e.Ticket]; ok && foundIndex.MaxCount < l { + maxCountFailed = true + break + } + } + if maxCountFailed { + continue + } + // Found a suitable match. entries, ok := m.entries[ticket] if !ok { diff --git a/server/runtime_javascript_test.go b/server/runtime_javascript_test.go index 33b97a5e2..e50eab6eb 100644 --- a/server/runtime_javascript_test.go +++ b/server/runtime_javascript_test.go @@ -15,11 +15,12 @@ package server import ( + "strings" + "testing" + "github.com/dop251/goja" "go.uber.org/zap" "go.uber.org/zap/zaptest/observer" - "strings" - "testing" ) func TestJsObjectFreeze(t *testing.T) { -- GitLab