@@ -6,17 +6,21 @@ import (
66 "errors"
77 "fmt"
88 "log"
9+ "os"
910 "sync"
1011
1112 "github.com/IBM/sarama"
1213 "github.com/Leo7Deng/ChatApp/cassandra"
1314 "github.com/Leo7Deng/ChatApp/models"
1415 "github.com/Leo7Deng/ChatApp/websockets"
1516 "github.com/gocql/gocql"
17+ "github.com/google/uuid"
18+ "github.com/jackc/pgx/v5/pgxpool"
1619)
1720
1821var hub * websockets.Hub
1922var cassandraSession * gocql.Session
23+ var pool * pgxpool.Pool
2024
2125func WebsocketConsumer (ctx context.Context , websocketHub * websockets.Hub ) {
2226 hub = websocketHub
@@ -32,6 +36,14 @@ func CassandraConsumer(ctx context.Context, session *gocql.Session) {
3236 runConsumer (ctx , groupID , handler )
3337}
3438
39+ func PostgresConsumer (ctx context.Context , postgresPool * pgxpool.Pool ) {
40+ pool = postgresPool
41+ groupID := "postgres-group"
42+ handler := & PostgresConsumerHandler {}
43+ runConsumer (ctx , groupID , handler )
44+ }
45+
46+
3547func runConsumer (ctx context.Context , groupID string , handler sarama.ConsumerGroupHandler ) {
3648 config := sarama .NewConfig ()
3749 config .Consumer .Return .Errors = true
@@ -74,6 +86,7 @@ func runConsumer(ctx context.Context, groupID string, handler sarama.ConsumerGro
7486
7587type WebsocketConsumerHandler struct {hub * websockets.Hub }
7688type CassandraConsumerHandler struct {}
89+ type PostgresConsumerHandler struct {}
7790
7891// Setup is run at the beginning of a new session, before ConsumeClaim
7992func (consumer * WebsocketConsumerHandler ) Setup (sarama.ConsumerGroupSession ) error {
@@ -82,6 +95,9 @@ func (consumer *WebsocketConsumerHandler) Setup(sarama.ConsumerGroupSession) err
8295func (consumer * CassandraConsumerHandler ) Setup (sarama.ConsumerGroupSession ) error {
8396 return nil
8497}
98+ func (consumer * PostgresConsumerHandler ) Setup (sarama.ConsumerGroupSession ) error {
99+ return nil
100+ }
85101
86102// Cleanup is run at the end of a session, once all ConsumeClaim goroutines have exited
87103func (consumer * WebsocketConsumerHandler ) Cleanup (sarama.ConsumerGroupSession ) error {
@@ -90,6 +106,9 @@ func (consumer *WebsocketConsumerHandler) Cleanup(sarama.ConsumerGroupSession) e
90106func (consumer * CassandraConsumerHandler ) Cleanup (sarama.ConsumerGroupSession ) error {
91107 return nil
92108}
109+ func (consumer * PostgresConsumerHandler ) Cleanup (sarama.ConsumerGroupSession ) error {
110+ return nil
111+ }
93112
94113// ConsumeClaim must start a consumer loop of ConsumerGroupClaim's Messages().
95114// Once the Messages() channel is closed, the Handler must finish its processing
@@ -159,4 +178,57 @@ func (consumer *CassandraConsumerHandler) ConsumeClaim(session sarama.ConsumerGr
159178 return nil
160179 }
161180 }
181+ }
182+
183+ func (consumer * PostgresConsumerHandler ) ConsumeClaim (session sarama.ConsumerGroupSession , claim sarama.ConsumerGroupClaim ) error {
184+ for {
185+ select {
186+ case message , ok := <- claim .Messages ():
187+ if ! ok {
188+ log .Printf ("message channel was closed" )
189+ return nil
190+ }
191+ partition , offset := message .Partition , message .Offset
192+ var websocketMessage models.WebsocketMessage
193+ err := json .Unmarshal (message .Value , & websocketMessage )
194+ if err != nil {
195+ fmt .Printf ("Failed to unmarshal message: %v\n " , err )
196+ }
197+ log .Printf ("Postgres consumer: %s | Partition: %d | Offset: %d\n " , message .Value , partition , offset )
198+ type InsertMessage struct {
199+ MessageID string `json:"message_id"`
200+ Message models.Message `json:"message"`
201+ }
202+ insertMessage := InsertMessage {
203+ MessageID : uuid .New ().String (),
204+ Message : models.Message {
205+ CircleID : websocketMessage .Message .CircleID ,
206+ AuthorID : websocketMessage .Message .AuthorID ,
207+ Content : websocketMessage .Message .Content ,
208+ CreatedAt : websocketMessage .Message .CreatedAt ,
209+ },
210+ }
211+ conn , err := pool .Acquire (session .Context ())
212+ if err != nil {
213+ fmt .Fprintf (os .Stderr , "Unable to acquire a connection from the pool: %v\n " , err )
214+ return err
215+ }
216+ defer conn .Release ()
217+
218+ _ , err = conn .Exec (
219+ session .Context (),
220+ "INSERT INTO messages (message_id, circle_id, author_id, content) VALUES ($1, $2, $3, $4)" ,
221+ insertMessage .MessageID ,
222+ insertMessage .Message .CircleID ,
223+ insertMessage .Message .AuthorID ,
224+ insertMessage .Message .Content ,
225+ )
226+ if err != nil {
227+ fmt .Fprintf (os .Stderr , "Error inserting into messages: %v\n " , err )
228+ return err
229+ }
230+ case <- session .Context ().Done ():
231+ return nil
232+ }
233+ }
162234}
0 commit comments