Skip to content

Commit c45f724

Browse files
committed
✨ feat: Add Request timeout & Improve Logging
1 parent 6b4bb6d commit c45f724

File tree

4 files changed

+34
-13
lines changed

4 files changed

+34
-13
lines changed

api/handlers.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,23 @@ func (h *BookHandler) AddBook(c echo.Context) error {
3131
}
3232

3333
func (h *BookHandler) SearchBooks(c echo.Context) error {
34+
ctx := c.Request().Context()
3435
query := c.QueryParam("q")
3536
if query == "" {
3637
return c.JSON(http.StatusBadRequest, echo.Map{"error": "missing query"})
3738
}
3839

39-
results, err := h.Service.SearchBooks(c.Request().Context(), query)
40+
select {
41+
case <-ctx.Done():
42+
return c.JSON(http.StatusRequestTimeout, echo.Map{"error": "request canceled or timed out"})
43+
default:
44+
}
45+
46+
results, err := h.Service.SearchBooks(ctx, query)
4047
if err != nil {
48+
if ctx.Err() != nil {
49+
return c.JSON(http.StatusRequestTimeout, echo.Map{"error": "request timed out"})
50+
}
4151
return c.JSON(http.StatusInternalServerError, echo.Map{"error": err.Error()})
4252
}
4353

cmd/main.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"log/slog"
88
"os"
9+
"time"
910

1011
"semantic-search/api"
1112
"semantic-search/internal/db"
@@ -85,6 +86,13 @@ func main() {
8586
e := echo.New()
8687
e.Use(middleware.Logger())
8788
e.Use(middleware.Recover())
89+
e.Use(middleware.TimeoutWithConfig(middleware.TimeoutConfig{
90+
Timeout: 5 * time.Second,
91+
ErrorMessage: "Request timed out.",
92+
OnTimeoutRouteErrorHandler: func(err error, c echo.Context) {
93+
logger.Warn("Timeout on route", "path", c.Path(), "error", err)
94+
},
95+
}))
8896

8997
// Routes
9098
e.GET("/ping", func(c echo.Context) error {

internal/db/db.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ func NewPool(ctx context.Context, dsn string, logger *slog.Logger) (*pgxpool.Poo
3434

3535
logger.Info("Pinging database to verify connection")
3636
if err := pool.Ping(ctx); err != nil {
37-
logger.Error("Failed to ping database", "error", err)
3837
pool.Close()
3938
return nil, fmt.Errorf("failed to ping database: %w", err)
4039
}

internal/service/book_service.go

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,11 @@ package service
22

33
import (
44
"context"
5-
"errors"
65
"fmt"
76
"log/slog"
87
"math"
98
"semantic-search/internal/embed"
109
"semantic-search/internal/repository"
11-
"time"
1210

1311
"github.com/pgvector/pgvector-go"
1412
)
@@ -48,28 +46,34 @@ func (s *BookService) AddBook(ctx context.Context, title, desc string) error {
4846

4947
// SearchBooks embeds the query, performs vector search, and ranks by cosine similarity.
5048
func (s *BookService) SearchBooks(ctx context.Context, query string) ([]BookWithSimilarity, error) {
49+
select {
50+
case <-ctx.Done():
51+
return nil, ctx.Err()
52+
default:
53+
}
54+
5155
vector, err := s.Embedder.Embed(ctx, query)
5256
if err != nil {
5357
s.Logger.Error("Embedding failed", "query", query, "error", err)
5458
return nil, fmt.Errorf("embedding failed: %w", err)
5559
}
5660

57-
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
58-
defer cancel()
59-
6061
books, err := s.Repository.SearchBooks(ctx, pgvector.NewVector(vector))
6162
if err != nil {
62-
if errors.Is(err, context.DeadlineExceeded) {
63-
s.Logger.Error("DB search timed out", "query", query)
64-
} else {
65-
s.Logger.Error("DB search failed", "query", query, "error", err)
66-
}
63+
s.Logger.Error("DB search failed", "query", query, "error", err)
6764
return nil, fmt.Errorf("db search failed: %w", err)
6865
}
6966

70-
// Calculate cosine similarity
67+
// Step 3: Post-process (cosine similarity) — respect ctx
7168
var results []BookWithSimilarity
7269
for _, book := range books {
70+
// Stop if request has been canceled
71+
select {
72+
case <-ctx.Done():
73+
return nil, ctx.Err()
74+
default:
75+
}
76+
7377
sim, err := cosineSimilarity(vector, book.Embedding.Slice())
7478
if err != nil {
7579
s.Logger.Warn("Failed to compute similarity", "bookID", book.ID, "error", err)

0 commit comments

Comments
 (0)