Skip to content

Commit c3fa821

Browse files
add redis
1 parent fd557df commit c3fa821

File tree

10 files changed

+320
-6
lines changed

10 files changed

+320
-6
lines changed

.env.docker

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,11 @@ APP_VERSION=1.0.0
1212

1313
POSTGRES_DB=forgotten_db
1414
POSTGRES_USER=forgotten_user
15-
POSTGRES_PASSWORD=123456
15+
POSTGRES_PASSWORD=123456
16+
17+
REDIS_ENABLED=true
18+
REDIS_ADDR=redis:6379
19+
REDIS_PASSWORD=
20+
REDIS_DB=0
21+
REDIS_TLS=false
22+
REDIS_CACHE_TTL_SECONDS=600

.env.example

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,11 @@ APP_VERSION=1.0.0
1212

1313
POSTGRES_DB=yourapp_db
1414
POSTGRES_USER=yourapp_user
15-
POSTGRES_PASSWORD=yourapp_password
15+
POSTGRES_PASSWORD=yourapp_password
16+
17+
REDIS_ENABLED=false
18+
REDIS_ADDR=redis:6379
19+
REDIS_PASSWORD=
20+
REDIS_DB=0
21+
REDIS_TLS=false
22+
REDIS_CACHE_TTL_SECONDS=600

docker/docker-compose.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,14 @@ services:
6060

6161
redis:
6262
image: redis:7-alpine
63+
command: ["redis-server", "--save", "60", "1", "--appendonly", "yes"]
6364
ports:
6465
- "6379:6379"
6566
restart: unless-stopped
6667
networks:
6768
- forgotten-network
69+
volumes:
70+
- redis_data:/data
6871

6972
prometheus:
7073
image: prom/prometheus:latest

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ require (
2323
github.com/cloudwego/base64x v0.1.5 // indirect
2424
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect
2525
github.com/davecgh/go-spew v1.1.1 // indirect
26+
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
2627
github.com/gabriel-vasile/mimetype v1.4.9 // indirect
2728
github.com/gin-contrib/sse v1.1.0 // indirect
2829
github.com/go-openapi/jsonpointer v0.19.5 // indirect
@@ -54,6 +55,7 @@ require (
5455
github.com/prometheus/client_model v0.6.2 // indirect
5556
github.com/prometheus/common v0.66.1 // indirect
5657
github.com/prometheus/procfs v0.16.1 // indirect
58+
github.com/redis/go-redis/v9 v9.14.0 // indirect
5759
github.com/russross/blackfriday/v2 v2.0.1 // indirect
5860
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
5961
github.com/swaggo/files v1.0.1 // indirect
@@ -79,6 +81,7 @@ require (
7981
require (
8082
github.com/gin-contrib/cors v1.7.6
8183
github.com/gin-gonic/gin v1.10.1
84+
github.com/go-redis/redis/v8 v8.11.5
8285
github.com/golang-jwt/jwt/v5 v5.3.0
8386
github.com/golang-migrate/migrate/v4 v4.19.0
8487
github.com/jinzhu/inflection v1.0.0 // indirect

go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
2323
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2424
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
2525
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
26+
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
27+
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
2628
github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY=
2729
github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok=
2830
github.com/gin-contrib/cors v1.7.6 h1:3gQ8GMzs1Ylpf70y8bMw4fVpycXIeX1ZemuSQIsnQQY=
@@ -49,6 +51,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
4951
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
5052
github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k=
5153
github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
54+
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
55+
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
5256
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
5357
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
5458
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
@@ -126,6 +130,8 @@ github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9Z
126130
github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
127131
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
128132
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
133+
github.com/redis/go-redis/v9 v9.14.0 h1:u4tNCjXOyzfgeLN+vAZaW1xUooqWDqVEsZN0U01jfAE=
134+
github.com/redis/go-redis/v9 v9.14.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
129135
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
130136
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
131137
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=

internal/config/config.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ type Config struct {
1313
Database DatabaseConfig
1414
JWT JWTConfig
1515
App AppConfig
16+
Redis RedisConfig
1617
}
1718

1819
type ServerConfig struct {
@@ -37,6 +38,15 @@ type AppConfig struct {
3738
Version string
3839
}
3940

41+
type RedisConfig struct {
42+
Enabled bool
43+
Addr string
44+
Password string
45+
DB int
46+
TLS bool
47+
CacheTTLSeconds int
48+
}
49+
4050
func Load() *Config {
4151
if err := godotenv.Load(); err != nil {
4252
log.Printf("no .env file found or error loading it: %v", err)
@@ -61,6 +71,14 @@ func Load() *Config {
6171
Name: getEnv("APP_NAME", "Forgotten"),
6272
Version: getEnv("APP_VERSION", "1.0.0"),
6373
},
74+
Redis: RedisConfig{
75+
Enabled: getEnvAsBool("REDIS_ENABLED", false),
76+
Addr: getEnv("REDIS_ADDR", "localhost:6379"),
77+
Password: getEnv("REDIS_PASSWORD", ""),
78+
DB: getEnvAsInt("REDIS_DB", 0),
79+
TLS: getEnvAsBool("REDIS_TLS", false),
80+
CacheTTLSeconds: getEnvAsInt("REDIS_CACHE_TTL_SECONDS", 600),
81+
},
6482
}
6583
}
6684

@@ -79,4 +97,18 @@ func getEnvAsInt(name string, defaultVal int) int {
7997
log.Printf("invalid integer value for %s: %s. using default: %d", name, value, defaultVal)
8098
}
8199
return defaultVal
100+
}
101+
102+
func getEnvAsBool(name string, defaultVal bool) bool {
103+
if value := os.Getenv(name); value != "" {
104+
switch value {
105+
case "1", "true", "TRUE", "True", "yes", "YES", "Yes", "on", "ON", "On":
106+
return true
107+
case "0", "false", "FALSE", "False", "no", "NO", "No", "off", "OFF", "Off":
108+
return false
109+
default:
110+
log.Printf("invalid boolean value for %s: %s. using default: %t", name, value, defaultVal)
111+
}
112+
}
113+
return defaultVal
82114
}

internal/handlers/server.go

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package handlers
22

33
import (
4+
"net/http"
5+
"time"
6+
47
_ "github.com/nevzattalhaozcan/forgotten/docs" // swag doc import
5-
"github.com/swaggo/gin-swagger"
6-
"github.com/swaggo/files"
8+
"github.com/nevzattalhaozcan/forgotten/pkg/cache"
9+
"github.com/nevzattalhaozcan/forgotten/pkg/logger"
710
"github.com/prometheus/client_golang/prometheus/promhttp"
8-
"net/http"
11+
"github.com/redis/go-redis/v9"
12+
"github.com/swaggo/files"
13+
"github.com/swaggo/gin-swagger"
914

1015
"github.com/gin-contrib/cors"
1116
"github.com/gin-gonic/gin"
@@ -41,7 +46,28 @@ func (s *Server) setupRoutes() {
4146

4247
s.router.HEAD("/health", func(c *gin.Context) { c.Status(http.StatusOK) })
4348

44-
userRepo := repository.NewUserRepository(s.db)
49+
var userRepo repository.UserRepository = repository.NewUserRepository(s.db)
50+
51+
var rdbAvailable bool
52+
var ttl time.Duration
53+
var rdb *redis.Client
54+
55+
if s.config.Redis.Enabled {
56+
client, err := cache.NewRedisClient(&s.config.Redis)
57+
if err != nil {
58+
logger.Warn("Redis enabled but connection failed, continuing without cache")
59+
} else {
60+
rdb = client
61+
rdbAvailable = true
62+
ttl = time.Duration(s.config.Redis.CacheTTLSeconds) * time.Second
63+
}
64+
}
65+
66+
if rdbAvailable {
67+
userRepo = repository.NewCachedUserRepository(userRepo, rdb, ttl)
68+
logger.Info("User repository caching enabled")
69+
}
70+
4571
userService := services.NewUserService(userRepo, s.config)
4672
userHandler := NewUserHandler(userService)
4773

0 commit comments

Comments
 (0)