@@ -18,78 +18,72 @@ import (
1818// until a match is found or no match and the user is enqueued to the queue.
1919func PerformMatching (rdb * redis.Client , matchRequest models.MatchRequest , ctx context.Context , errorChan chan error ) {
2020 currentUsername := matchRequest .Username
21- keys := []string {databases .MatchmakingQueueRedisKey , currentUsername }
22- for _ , topic := range matchRequest .Topics {
23- keys = append (keys , topic )
21+
22+ // Obtain lock with retry
23+ lock , err := databases .ObtainRedisLock (ctx )
24+ if err != nil {
25+ return
2426 }
25- for true {
27+ defer lock . Release ( ctx )
2628
27- err := rdb .Watch (ctx , func (tx * redis.Tx ) error {
28- queuedUsernames , err := databases .GetAllQueuedUsers (tx , ctx )
29- if err != nil {
30- return err
31- }
29+ if err := rdb .Watch (ctx , func (tx * redis.Tx ) error {
30+ queuedUsernames , err := databases .GetAllQueuedUsers (tx , ctx )
31+ if err != nil {
32+ return err
33+ }
3234
33- // Check that user is not part of the existing queue
34- for _ , username := range queuedUsernames {
35- if username == currentUsername {
36- return models .ExistingUserError
37- }
35+ // Check that user is not part of the existing queue
36+ for _ , username := range queuedUsernames {
37+ if username == currentUsername {
38+ return models .ExistingUserError
3839 }
40+ }
3941
40- databases .AddUser (tx , matchRequest , ctx )
42+ databases .AddUser (tx , matchRequest , ctx )
4143
42- // Log queue before and after matchmaking
43- databases .PrintMatchingQueue (tx , "Before Matchmaking" , ctx )
44- defer databases .PrintMatchingQueue (tx , "After Matchmaking" , ctx )
44+ // Log queue before and after matchmaking
45+ databases .PrintMatchingQueue (tx , "Before Matchmaking" , ctx )
46+ defer databases .PrintMatchingQueue (tx , "After Matchmaking" , ctx )
47+ // Find a matching user if any
48+ matchFound , err := databases .FindMatchingUser (tx , currentUsername , ctx )
49+ if err != nil {
50+ log .Println ("Error finding matching user:" , err )
51+ return err
52+ }
4553
46- // Find a matching user if any
47- matchFound , err := databases .FindMatchingUser (tx , currentUsername , ctx )
54+ if matchFound != nil {
55+ matchedUsername := matchFound .MatchedUser
56+ matchedTopic := matchFound .Topic
57+ matchedDifficulty := matchFound .Difficulty
58+
59+ // Generate a random match ID
60+ matchId , err := utils .GenerateMatchID ()
4861 if err != nil {
49- log .Println ("Error finding matching user:" , err )
50- return err
62+ log .Println ("Unable to randomly generate matchID" )
5163 }
5264
53- if matchFound != nil {
54- matchedUsername := matchFound .MatchedUser
55- matchedTopic := matchFound .Topic
56- matchedDifficulty := matchFound .Difficulty
57-
58- // Generate a random match ID
59- matchId , err := utils .GenerateMatchID ()
60- if err != nil {
61- log .Println ("Unable to randomly generate matchID" )
62- }
65+ // Log down which users got matched
66+ matchFound .MatchID = matchId
67+ log .Printf ("Users %s and %s matched on the topic: %s with difficulty: %s" , currentUsername , matchedUsername , matchedTopic , matchedDifficulty )
6368
64- // Log down which users got matched
65- matchFound . MatchID = matchId
66- log . Printf ( "Users %s and %s matched on the topic: %s with difficulty: %s" , currentUsername , matchedUsername , matchedTopic , matchedDifficulty )
69+ // Clean up redis for this match
70+ databases . CleanUpUser ( tx , currentUsername , ctx )
71+ databases . CleanUpUser ( tx , matchedUsername , ctx )
6772
68- // Clean up redis for this match
69- databases .CleanUpUser (tx , currentUsername , ctx )
70- databases .CleanUpUser (tx , matchedUsername , ctx )
71-
72- publishMatch (tx , ctx , currentUsername , matchedUsername , matchFound )
73- publishMatch (tx , ctx , matchedUsername , currentUsername , matchFound )
74- }
73+ publishMatch (tx , ctx , currentUsername , matchedUsername , matchFound )
74+ publishMatch (tx , ctx , matchedUsername , currentUsername , matchFound )
75+ }
7576
76- time .Sleep (time .Duration (time .Second * 1 ))
77+ time .Sleep (time .Duration (time .Second * 1 ))
7778
78- return nil
79- }, keys ... )
80- if err != nil {
81- // return
82- if errors .Is (err , models .ExistingUserError ) {
83- errorChan <- err
84- break
85- } else {
86- // transaction failed, so will retry
87- println (fmt .Errorf ("transaction execution failed: %v" , err ))
88- }
89- }
90- if err == nil {
91- // transaction succeeded
92- break
79+ return nil
80+ }); err != nil {
81+ // return
82+ if errors .Is (err , models .ExistingUserError ) {
83+ errorChan <- err
84+ } else {
85+ // transaction failed, no retry
86+ println (fmt .Errorf ("transaction execution failed: %v" , err ))
9387 }
9488 }
9589}
0 commit comments