88 "gpt-load/internal/models"
99 "gpt-load/internal/store"
1010 "strings"
11+ "sync"
1112 "time"
1213
1314 "github.com/google/uuid"
@@ -28,61 +29,77 @@ type RequestLogService struct {
2829 store store.Store
2930 settingsManager * config.SystemSettingsManager
3031 leaderLock * store.LeaderLock
31- ctx context. Context
32- cancel context. CancelFunc
32+ stopChan chan struct {}
33+ wg sync. WaitGroup
3334 ticker * time.Ticker
3435}
3536
3637// NewRequestLogService creates a new RequestLogService instance
3738func NewRequestLogService (db * gorm.DB , store store.Store , sm * config.SystemSettingsManager , ls * store.LeaderLock ) * RequestLogService {
38- ctx , cancel := context .WithCancel (context .Background ())
3939 return & RequestLogService {
4040 db : db ,
4141 store : store ,
4242 settingsManager : sm ,
4343 leaderLock : ls ,
44- ctx : ctx ,
45- cancel : cancel ,
44+ stopChan : make (chan struct {}),
4645 }
4746}
4847
4948// Start initializes the service and starts the periodic flush routine
5049func (s * RequestLogService ) Start () {
51- go s .flush ()
50+ s .wg .Add (1 )
51+ go s .runLoop ()
52+ }
53+
54+ func (s * RequestLogService ) runLoop () {
55+ defer s .wg .Done ()
56+
57+ // Initial flush on start
58+ s .flush ()
5259
5360 interval := time .Duration (s .settingsManager .GetSettings ().RequestLogWriteIntervalMinutes ) * time .Minute
5461 if interval <= 0 {
5562 interval = time .Minute
5663 }
5764 s .ticker = time .NewTicker (interval )
65+ defer s .ticker .Stop ()
5866
59- go func () {
60- for {
61- select {
62- case <- s .ticker .C :
63- newInterval := time .Duration (s .settingsManager .GetSettings ().RequestLogWriteIntervalMinutes ) * time .Minute
64- if newInterval <= 0 {
65- newInterval = time .Minute
66- }
67- if newInterval != interval {
68- s .ticker .Reset (newInterval )
69- interval = newInterval
70- logrus .Debugf ("Request log write interval updated to: %v" , interval )
71- }
72- s .flush ()
73- case <- s .ctx .Done ():
74- s .ticker .Stop ()
75- logrus .Info ("RequestLogService stopped." )
76- return
67+ for {
68+ select {
69+ case <- s .ticker .C :
70+ newInterval := time .Duration (s .settingsManager .GetSettings ().RequestLogWriteIntervalMinutes ) * time .Minute
71+ if newInterval <= 0 {
72+ newInterval = time .Minute
73+ }
74+ if newInterval != interval {
75+ s .ticker .Reset (newInterval )
76+ interval = newInterval
77+ logrus .Debugf ("Request log write interval updated to: %v" , interval )
7778 }
79+ s .flush ()
80+ case <- s .stopChan :
81+ return
7882 }
79- }()
83+ }
8084}
8185
8286// Stop gracefully stops the RequestLogService
83- func (s * RequestLogService ) Stop () {
84- s .flush ()
85- s .cancel ()
87+ func (s * RequestLogService ) Stop (ctx context.Context ) {
88+ close (s .stopChan )
89+
90+ done := make (chan struct {})
91+ go func () {
92+ s .wg .Wait ()
93+ close (done )
94+ }()
95+
96+ select {
97+ case <- done :
98+ s .flush ()
99+ logrus .Info ("RequestLogService stopped gracefully." )
100+ case <- ctx .Done ():
101+ logrus .Warn ("RequestLogService stop timed out." )
102+ }
86103}
87104
88105// Record logs a request to the database and cache
0 commit comments