@@ -8,70 +8,87 @@ import (
88 "matching-service/databases"
99 "matching-service/models"
1010 "matching-service/utils"
11+ "time"
1112
1213 "github.com/redis/go-redis/v9"
1314)
1415
1516// Performs the matching algorithm at most once starting from the front of the queue of users,
1617// until a match is found or no match and the user is enqueued to the queue.
1718func PerformMatching (rdb * redis.Client , matchRequest models.MatchRequest , ctx context.Context , errorChan chan error ) {
18- err := rdb .Watch (ctx , func (tx * redis.Tx ) error {
19- // Log queue before and after matchmaking
20- databases .PrintMatchingQueue (tx , "Before Matchmaking" , ctx )
21- defer databases .PrintMatchingQueue (tx , "After Matchmaking" , ctx )
19+ currentUsername := matchRequest .Username
20+ keys := []string {databases .MatchmakingQueueRedisKey , currentUsername }
21+ for _ , topic := range matchRequest .Topics {
22+ keys = append (keys , topic )
23+ }
24+ for true {
2225
23- currentUsername := matchRequest .Username
24- queuedUsernames , err := databases .GetAllQueuedUsers (tx , ctx )
25- if err != nil {
26- return err
27- }
26+ err := rdb .Watch (ctx , func (tx * redis.Tx ) error {
27+ // Log queue before and after matchmaking
28+ databases .PrintMatchingQueue (tx , "Before Matchmaking" , ctx )
29+ defer databases .PrintMatchingQueue (tx , "After Matchmaking" , ctx )
2830
29- // Check that user is not part of the existing queue
30- for _ , username := range queuedUsernames {
31- if username == currentUsername {
32- return models .ExistingUserError
31+ queuedUsernames , err := databases .GetAllQueuedUsers (tx , ctx )
32+ if err != nil {
33+ return err
3334 }
34- }
3535
36- databases .AddUser (tx , matchRequest , ctx )
37-
38- // Find a matching user if any
39- matchFound , err := databases .FindMatchingUser (tx , currentUsername , ctx )
40- if err != nil {
41- log .Println ("Error finding matching user:" , err )
42- return err
43- }
36+ // Check that user is not part of the existing queue
37+ for _ , username := range queuedUsernames {
38+ if username == currentUsername {
39+ return models .ExistingUserError
40+ }
41+ }
4442
45- if matchFound != nil {
46- matchedUsername := matchFound .MatchedUser
47- matchedTopic := matchFound .Topic
48- matchedDifficulty := matchFound .Difficulty
43+ databases .AddUser (tx , matchRequest , ctx )
4944
50- // Generate a random match ID
51- matchId , err := utils . GenerateMatchID ( )
45+ // Find a matching user if any
46+ matchFound , err := databases . FindMatchingUser ( tx , currentUsername , ctx )
5247 if err != nil {
53- log .Println ("Unable to randomly generate matchID" )
48+ log .Println ("Error finding matching user:" , err )
49+ return err
5450 }
5551
56- // Log down which users got matched
57- matchFound .MatchID = matchId
58- log .Printf ("Users %s and %s matched on the topic: %s with difficulty: %s" , currentUsername , matchedUsername , matchedTopic , matchedDifficulty )
52+ if matchFound != nil {
53+ matchedUsername := matchFound .MatchedUser
54+ matchedTopic := matchFound .Topic
55+ matchedDifficulty := matchFound .Difficulty
5956
60- // Clean up redis for this match
61- databases .CleanUpUser (tx , currentUsername , ctx )
62- databases .CleanUpUser (tx , matchedUsername , ctx )
57+ // Generate a random match ID
58+ matchId , err := utils .GenerateMatchID ()
59+ if err != nil {
60+ log .Println ("Unable to randomly generate matchID" )
61+ }
6362
64- publishMatch ( tx , ctx , currentUsername , matchedUsername , matchFound )
65- publishMatch ( tx , ctx , matchedUsername , currentUsername , matchFound )
66- }
63+ // Log down which users got matched
64+ matchFound . MatchID = matchId
65+ log . Printf ( "Users %s and %s matched on the topic: %s with difficulty: %s" , currentUsername , matchedUsername , matchedTopic , matchedDifficulty )
6766
68- return nil
69- })
70- if err != nil {
71- // Handle error (like retry logic could be added here)
72- // return fmt.Errorf("transaction execution failed: %v", err)
73- if errors .Is (err , models .ExistingUserError ) {
74- errorChan <- err
67+ // Clean up redis for this match
68+ databases .CleanUpUser (tx , currentUsername , ctx )
69+ databases .CleanUpUser (tx , matchedUsername , ctx )
70+
71+ publishMatch (tx , ctx , currentUsername , matchedUsername , matchFound )
72+ publishMatch (tx , ctx , matchedUsername , currentUsername , matchFound )
73+ }
74+
75+ time .Sleep (time .Duration (time .Second * 1 ))
76+
77+ return nil
78+ }, keys ... )
79+ if err != nil {
80+ // transaction failed
81+ println (err )
82+ // Handle error (like retry logic could be added here)
83+ // return fmt.Errorf("transaction execution failed: %v", err)
84+ if errors .Is (err , models .ExistingUserError ) {
85+ errorChan <- err
86+ break
87+ }
88+ }
89+ if err == nil {
90+ // transaction succeeded
91+ break
7592 }
7693 }
7794}
0 commit comments