@@ -4,9 +4,11 @@ import (
44 "context"
55 "errors"
66 "fmt"
7+ "time"
78
89 "github.com/NdoleStudio/httpsms/pkg/entities"
910 "github.com/NdoleStudio/httpsms/pkg/telemetry"
11+ "github.com/dgraph-io/ristretto/v2"
1012 "github.com/google/uuid"
1113 "github.com/palantir/stacktrace"
1214 "gorm.io/gorm"
@@ -16,6 +18,7 @@ import (
1618type gormPhoneRepository struct {
1719 logger telemetry.Logger
1820 tracer telemetry.Tracer
21+ cache * ristretto.Cache [string , * entities.Phone ]
1922 db * gorm.DB
2023}
2124
@@ -24,11 +27,13 @@ func NewGormPhoneRepository(
2427 logger telemetry.Logger ,
2528 tracer telemetry.Tracer ,
2629 db * gorm.DB ,
30+ cache * ristretto.Cache [string , * entities.Phone ],
2731) PhoneRepository {
2832 return & gormPhoneRepository {
2933 logger : logger .WithService (fmt .Sprintf ("%T" , & gormPhoneRepository {})),
3034 tracer : tracer ,
3135 db : db ,
36+ cache : cache ,
3237 }
3338}
3439
@@ -41,6 +46,7 @@ func (repository *gormPhoneRepository) DeleteAllForUser(ctx context.Context, use
4146 return repository .tracer .WrapErrorSpan (span , stacktrace .Propagate (err , msg ))
4247 }
4348
49+ repository .cache .Clear ()
4450 return nil
4551}
4652
@@ -81,6 +87,7 @@ func (repository *gormPhoneRepository) Delete(ctx context.Context, userID entiti
8187 return repository .tracer .WrapErrorSpan (span , stacktrace .Propagate (err , msg ))
8288 }
8389
90+ repository .cache .Clear ()
8491 return nil
8592}
8693
@@ -106,14 +113,20 @@ func (repository *gormPhoneRepository) Save(ctx context.Context, phone *entities
106113 return repository .tracer .WrapErrorSpan (span , stacktrace .Propagate (err , msg ))
107114 }
108115
116+ repository .cache .Del (repository .getCacheKey (phone .UserID , phone .PhoneNumber ))
109117 return nil
110118}
111119
112120// Load a phone based on entities.UserID and phoneNumber
113121func (repository * gormPhoneRepository ) Load (ctx context.Context , userID entities.UserID , phoneNumber string ) (* entities.Phone , error ) {
114- ctx , span := repository .tracer .Start (ctx )
122+ ctx , span , ctxLogger := repository .tracer .StartWithLogger (ctx , repository . logger )
115123 defer span .End ()
116124
125+ if phone , found := repository .cache .Get (repository .getCacheKey (userID , phoneNumber )); found {
126+ ctxLogger .Info (fmt .Sprintf ("cache hit for [%T] with ID [%s]" , phone , userID ))
127+ return phone , nil
128+ }
129+
117130 phone := new (entities.Phone )
118131 err := repository .db .WithContext (ctx ).Where ("user_id = ?" , userID ).Where ("phone_number = ?" , phoneNumber ).First (phone ).Error
119132 if errors .Is (err , gorm .ErrRecordNotFound ) {
@@ -126,6 +139,11 @@ func (repository *gormPhoneRepository) Load(ctx context.Context, userID entities
126139 return nil , repository .tracer .WrapErrorSpan (span , stacktrace .Propagate (err , msg ))
127140 }
128141
142+ if result := repository .cache .SetWithTTL (repository .getCacheKey (userID , phoneNumber ), phone , 1 , 30 * time .Minute ); ! result {
143+ msg := fmt .Sprintf ("cannot cache [%T] with ID [%s] and result [%t]" , phone , phone .ID , result )
144+ ctxLogger .Error (repository .tracer .WrapErrorSpan (span , stacktrace .NewError (msg )))
145+ }
146+
129147 return phone , nil
130148}
131149
@@ -147,3 +165,7 @@ func (repository *gormPhoneRepository) Index(ctx context.Context, userID entitie
147165
148166 return phones , nil
149167}
168+
169+ func (repository * gormPhoneRepository ) getCacheKey (userID entities.UserID , phoneNumber string ) string {
170+ return fmt .Sprintf ("user:%s:phone:%s" , userID , phoneNumber )
171+ }
0 commit comments