@@ -2,13 +2,11 @@ package service
22
33import (
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.
5048func (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