Skip to content

Commit dbcdc69

Browse files
committed
feat: implement grpc client
1 parent 0cd12f8 commit dbcdc69

File tree

7 files changed

+83
-20
lines changed

7 files changed

+83
-20
lines changed

apps/matching-service/databases/userqueue.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"log"
88
"matching-service/models"
9+
"matching-service/servers"
910
"strings"
1011

1112
"github.com/redis/go-redis/v9"
@@ -30,7 +31,7 @@ func PrintMatchingQueue(tx *redis.Tx, status string, ctx context.Context) {
3031
}
3132

3233
func IsQueueEmpty(tx *redis.Tx, ctx context.Context) (bool, error) {
33-
queueLength, err := tx.LLen(ctx, MatchmakingQueueRedisKey).Result()
34+
queueLength, err := tx.LLen(ctx, servers.MatchmakingQueueRedisKey).Result()
3435
if err != nil {
3536
log.Println("Error checking queue length:", err)
3637
return false, err
@@ -41,15 +42,15 @@ func IsQueueEmpty(tx *redis.Tx, ctx context.Context) (bool, error) {
4142

4243
// Enqueue a user into the matchmaking queue
4344
func EnqueueUser(tx *redis.Tx, username string, ctx context.Context) {
44-
err := tx.LPush(ctx, MatchmakingQueueRedisKey, username).Err()
45+
err := tx.LPush(ctx, servers.MatchmakingQueueRedisKey, username).Err()
4546
if err != nil {
4647
log.Println("Error enqueuing user:", err)
4748
}
4849
}
4950

5051
// Remove user from the matchmaking queue
5152
func DequeueUser(tx *redis.Tx, username string, ctx context.Context) {
52-
err := tx.LRem(ctx, MatchmakingQueueRedisKey, 1, username).Err()
53+
err := tx.LRem(ctx, servers.MatchmakingQueueRedisKey, 1, username).Err()
5354
if err != nil {
5455
log.Println("Error dequeuing user:", err)
5556
return
@@ -59,7 +60,7 @@ func DequeueUser(tx *redis.Tx, username string, ctx context.Context) {
5960
// Returns the first user's username from the queue.
6061
func GetFirstUser(tx *redis.Tx, ctx context.Context) (string, error) {
6162
// Peek at the user queue
62-
username, err := tx.LIndex(ctx, MatchmakingQueueRedisKey, 0).Result()
63+
username, err := tx.LIndex(ctx, servers.MatchmakingQueueRedisKey, 0).Result()
6364
if err != nil {
6465
log.Println("Error peeking user from queue:", err)
6566
return "", err
@@ -69,7 +70,7 @@ func GetFirstUser(tx *redis.Tx, ctx context.Context) (string, error) {
6970

7071
// Return the usernames of all the queued users.
7172
func GetAllQueuedUsers(tx *redis.Tx, ctx context.Context) ([]string, error) {
72-
users, err := tx.LRange(ctx, MatchmakingQueueRedisKey, 0, -1).Result()
73+
users, err := tx.LRange(ctx, servers.MatchmakingQueueRedisKey, 0, -1).Result()
7374
if err != nil {
7475
log.Println("Error retrieving users from queue:", err)
7576
return nil, err
@@ -165,13 +166,13 @@ func RemoveUserDetails(tx *redis.Tx, username string, ctx context.Context) {
165166

166167
func PopAndInsertUser(tx *redis.Tx, username string, ctx context.Context) {
167168
// Pop user
168-
username, err := tx.LPop(ctx, MatchmakingQueueRedisKey).Result()
169+
username, err := tx.LPop(ctx, servers.MatchmakingQueueRedisKey).Result()
169170
if err != nil {
170171
log.Println("Error popping user from queue:", err)
171172
}
172173

173174
// Insert back in queue
174-
err = tx.LPush(ctx, MatchmakingQueueRedisKey, username).Err()
175+
err = tx.LPush(ctx, servers.MatchmakingQueueRedisKey, username).Err()
175176
if err != nil {
176177
log.Println("Error enqueuing user:", err)
177178
}

apps/matching-service/handlers/websocket.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"matching-service/databases"
99
"matching-service/models"
1010
"matching-service/processes"
11+
"matching-service/servers"
1112
"matching-service/utils"
1213
"net/http"
1314

@@ -26,7 +27,7 @@ var (
2627

2728
// handleConnections manages WebSocket connections and matching logic.
2829
func HandleWebSocketConnections(w http.ResponseWriter, r *http.Request) {
29-
rdb := databases.GetRedisClient()
30+
rdb := servers.GetRedisClient()
3031
ctx := context.Background()
3132

3233
// TODO: Parse the authorization header to validate the JWT token and get the user ID claim.
@@ -93,11 +94,11 @@ func readMatchRequest(ws *websocket.Conn) (models.MatchRequest, error) {
9394
// If user is already removed, then nothing happens.
9495
// This function is unaffected by the external context.
9596
func cleanUpUser(username string) {
96-
redisClient := databases.GetRedisClient()
97+
redisClient := servers.GetRedisClient()
9798
ctx := context.Background()
9899

99100
// Obtain lock with retry
100-
lock, err := databases.ObtainRedisLock(ctx)
101+
lock, err := servers.ObtainRedisLock(ctx)
101102
if err != nil {
102103
return
103104
}

apps/matching-service/main.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ package main
33
import (
44
"fmt"
55
"log"
6-
"matching-service/databases"
76
"matching-service/handlers"
7+
"matching-service/servers"
88
"net/http"
99
"os"
1010

@@ -13,8 +13,10 @@ import (
1313

1414
func main() {
1515
setUpEnvironment()
16-
client := databases.SetupRedisClient()
16+
client := servers.SetupRedisClient()
1717
defer client.Close()
18+
grpcClient := servers.InitGrpcServer()
19+
defer grpcClient.Close()
1820
setupRoutes()
1921
startServer()
2022
}

apps/matching-service/processes/performmatches.go

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import (
88
"log"
99
"matching-service/databases"
1010
"matching-service/models"
11+
pb "matching-service/proto"
12+
"matching-service/servers"
13+
"time"
1114

1215
"github.com/redis/go-redis/v9"
1316
)
@@ -18,7 +21,7 @@ func PerformMatching(rdb *redis.Client, matchRequest models.MatchRequest, ctx co
1821
currentUsername := matchRequest.Username
1922

2023
// Obtain lock with retry
21-
lock, err := databases.ObtainRedisLock(ctx)
24+
lock, err := servers.ObtainRedisLock(ctx)
2225
if err != nil {
2326
return
2427
}
@@ -38,27 +41,53 @@ func PerformMatching(rdb *redis.Client, matchRequest models.MatchRequest, ctx co
3841
// Find a matching user if any
3942
matchFound, err := findMatchingUsers(tx, currentUsername, ctx)
4043
if err != nil {
44+
if errors.Is(err, models.NoMatchFound) {
45+
return nil
46+
}
4147
log.Println("Error finding matching user:", err)
4248
return err
43-
} else if matchFound != nil {
49+
} else if matchFound != nil && err != models.NoMatchFound {
4450
matchedUsername := matchFound.MatchedUser
4551
matchedTopics := matchFound.MatchedTopics
4652
matchedDifficulties := matchFound.MatchedDifficulties
4753

4854
// Log down which users got matched
49-
log.Printf("Users %s and %s matched on the topics: %v with difficulties: %v", currentUsername, matchedUsername, matchedTopics, matchedDifficulties)
55+
log.Printf("Users %s and %s matched on the topics: %v; with difficulties: %v", currentUsername, matchedUsername, matchedTopics, matchedDifficulties)
5056

5157
// Clean up redis for this match
5258
databases.CleanUpUser(tx, currentUsername, ctx)
5359
databases.CleanUpUser(tx, matchedUsername, ctx)
5460

55-
publishMatch(tx, ctx, currentUsername, matchedUsername, matchFound)
56-
publishMatch(tx, ctx, matchedUsername, currentUsername, matchFound)
61+
// Query question service to find a question for the match
62+
ctx2, cancel := context.WithTimeout(ctx, time.Second)
63+
defer cancel()
64+
65+
question, err := servers.GetGrpcClient().FindMatchingQuestion(ctx2, &pb.MatchQuestionRequest{
66+
MatchedTopics: matchedTopics,
67+
MatchedDifficulties: matchedDifficulties,
68+
})
69+
if err != nil {
70+
log.Fatalf("Could not retrieve question from question-service: %v", err)
71+
}
72+
73+
matchQuestionFound := models.MatchQuestionFound{
74+
Type: "match_found",
75+
MatchID: matchFound.MatchID,
76+
User: matchFound.User,
77+
MatchedUser: matchFound.MatchedUser,
78+
MatchedTopics: matchedTopics,
79+
QuestionID: question.QuestionId,
80+
QuestionName: question.QuestionName,
81+
QuestionDifficulty: question.QuestionDifficulty,
82+
QuestionTopics: question.QuestionTopics,
83+
}
84+
85+
publishMatch(tx, ctx, currentUsername, matchedUsername, &matchQuestionFound)
86+
publishMatch(tx, ctx, matchedUsername, currentUsername, &matchQuestionFound)
5787
}
5888

5989
return nil
6090
}); err != nil {
61-
// return
6291
if errors.Is(err, models.ExistingUserError) {
6392
errorChan <- err
6493
} else {
@@ -69,7 +98,7 @@ func PerformMatching(rdb *redis.Client, matchRequest models.MatchRequest, ctx co
6998
}
7099

71100
// Publish a match to the target user's pub/sub channel
72-
func publishMatch(tx *redis.Tx, ctx context.Context, targetUser string, otherMatchedUser string, matchFound *models.MatchFound) error {
101+
func publishMatch(tx *redis.Tx, ctx context.Context, targetUser string, otherMatchedUser string, matchFound *models.MatchQuestionFound) error {
73102
matchFound.User = targetUser
74103
matchFound.MatchedUser = otherMatchedUser
75104
msg, err := json.Marshal(matchFound)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package servers
2+
3+
import (
4+
"log"
5+
pb "matching-service/proto"
6+
7+
"google.golang.org/grpc"
8+
)
9+
10+
var (
11+
questionMatchingClient pb.QuestionMatchingServiceClient
12+
)
13+
14+
func InitGrpcServer() *grpc.ClientConn {
15+
// Dial the server
16+
conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
17+
if err != nil {
18+
log.Fatalf("Did not connect: %v", err)
19+
}
20+
21+
// Create a new client for the ExampleService
22+
questionMatchingClient = pb.NewQuestionMatchingServiceClient(conn)
23+
24+
return conn
25+
}
26+
27+
func GetGrpcClient() pb.QuestionMatchingServiceClient {
28+
return questionMatchingClient
29+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package databases
1+
package servers
22

33
import (
44
"context"

apps/question-service/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ func initGrpcServer() {
129129
}
130130

131131
func (s *server) FindMatchingQuestion(ctx context.Context, req *pb.MatchQuestionRequest) (*pb.QuestionFound, error) {
132+
// STUB
132133
return &pb.QuestionFound{
133134
QuestionId: 1,
134135
QuestionName: "abc",

0 commit comments

Comments
 (0)