11package main
22
33import (
4+ "errors"
45 "fmt"
56 "net/http"
7+ "os"
8+ "os/signal"
9+ "syscall"
610 "time"
711
812 "github.com/go-chi/chi/v5"
@@ -12,10 +16,12 @@ import (
1216 _ "github.com/karthikbhandary2/Social/docs"
1317 "github.com/karthikbhandary2/Social/internal/auth"
1418 "github.com/karthikbhandary2/Social/internal/mailer"
19+ "github.com/karthikbhandary2/Social/internal/ratelimiter"
1520 "github.com/karthikbhandary2/Social/internal/store"
1621 "github.com/karthikbhandary2/Social/internal/store/cache"
1722 "github.com/swaggo/http-swagger/v2"
1823 "go.uber.org/zap"
24+ "golang.org/x/net/context"
1925)
2026
2127type application struct {
@@ -25,6 +31,7 @@ type application struct {
2531 logger * zap.SugaredLogger
2632 mailer mailer.Client
2733 authenticator auth.Authenticator
34+ rateLimiter ratelimiter.Limiter
2835}
2936
3037type config struct {
@@ -36,6 +43,7 @@ type config struct {
3643 frontendURL string
3744 auth authConfig
3845 redisCfg redisConfig
46+ rateLimiter ratelimiter.Config
3947}
4048
4149type redisConfig struct {
@@ -94,10 +102,10 @@ func (app *application) mount() http.Handler {
94102 r .Use (middleware .Logger )
95103 r .Use (middleware .RealIP )
96104 r .Use (middleware .RequestID )
97- r .Use (middleware . Timeout ( 60 * time . Second ) )
105+ r .Use (app . RateLimiterMiddleware )
98106
99107 r .Route ("/v1" , func (r chi.Router ) {
100- r .With ( app . BasicAuthMiddleware ()). Get ("/health" , app .healthCheckHandler )
108+ r .Get ("/health" , app .healthCheckHandler )
101109
102110 docsURL := fmt .Sprintf ("%s/swagger/doc.json" , app .config .addr )
103111 r .Get ("/swagger/*" , httpSwagger .Handler (httpSwagger .URL (docsURL )))
@@ -149,6 +157,30 @@ func (app *application) run(mux http.Handler) error {
149157 ReadTimeout : time .Second * 10 , // It should be less than writes
150158 IdleTimeout : time .Minute ,
151159 }
160+
161+ shutdown := make (chan error )
162+ go func () {
163+ quit := make (chan os.Signal , 1 )
164+ signal .Notify (quit , syscall .SIGINT , syscall .SIGTERM )
165+ s := <- quit
166+
167+ ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
168+ defer cancel ()
169+
170+ app .logger .Infow ("signal caught" , "signal" , s .String ())
171+
172+ shutdown <- srv .Shutdown (ctx )
173+ }()
152174 app .logger .Infow ("server has started" , "addr" , app .config .addr , "env" , app .config .env )
153- return srv .ListenAndServe ()
175+
176+ err := srv .ListenAndServe ()
177+ if ! errors .Is (err , http .ErrServerClosed ) {
178+ return err
179+ }
180+ err = <- shutdown
181+ if err != nil {
182+ return err
183+ }
184+ app .logger .Infow ("server has stopped" , "addr" , app .config .addr , "env" , app .config .env )
185+ return nil
154186}
0 commit comments