fix(backup): pozadinske gorutine koriste svežu konekciju posle obnove
Auto-backup i čišćenje sesija/pokušaja su koristili originalni db handle iz main.go, koji posle obnove backupa (VratiBackup) ostaje zatvoren — gorutine bi prestale da rade do restarta. Sada rade preko novog helpera h.SaBazom, koji pod deljenim zaključavanjem prosleđuje trenutnu h.DB, pa vide zamenjenu konekciju. Gorutine su premeštene da startuju posle kreiranja h. time.Sleep je van zaključavanja da ne odlaže obnovu.
This commit is contained in:
+30
-22
@@ -109,28 +109,6 @@ func main() {
|
|||||||
|
|
||||||
napraviBackup(db, putanjaBaze)
|
napraviBackup(db, putanjaBaze)
|
||||||
|
|
||||||
// periodični automatski backup — interval se čita iz podešavanja u svakom ciklusu,
|
|
||||||
// tako da izmena u podešavanjima stupa na snagu bez restarta (od sledećeg ciklusa)
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
sati := procitajIntPodesavanje(db, "backup_interval_sati", 24)
|
|
||||||
time.Sleep(time.Duration(sati) * time.Hour)
|
|
||||||
napraviBackup(db, putanjaBaze)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
// periodično brisanje isteklih sesija i starih pokušaja prijave
|
|
||||||
go func() {
|
|
||||||
ticker := time.NewTicker(time.Hour)
|
|
||||||
defer ticker.Stop()
|
|
||||||
sesijeRepo := sqlite.NoviSesijeRepo(db)
|
|
||||||
pokusajiRepo := sqlite.NoviPokusajiPrijaveRepo(db)
|
|
||||||
for range ticker.C {
|
|
||||||
_ = sesijeRepo.ObrisiIstekle(context.Background())
|
|
||||||
_ = pokusajiRepo.ObrisiStare(context.Background(), time.Now().Add(-24*time.Hour))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
os.MkdirAll("web/static/uploads", 0755)
|
os.MkdirAll("web/static/uploads", 0755)
|
||||||
|
|
||||||
h := handler.Novi(db, totpKljuc)
|
h := handler.Novi(db, totpKljuc)
|
||||||
@@ -151,6 +129,36 @@ func main() {
|
|||||||
log.Printf("Keš šablona kreiran: %d šablona", len(kes))
|
log.Printf("Keš šablona kreiran: %d šablona", len(kes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pozadinske gorutine se pokreću posle kreiranja h i rade preko h.SaBazom,
|
||||||
|
// pa uvek koriste TRENUTNU konekciju baze (posle obnove backupa h.DB se menja).
|
||||||
|
|
||||||
|
// periodični automatski backup — interval se čita iz podešavanja u svakom
|
||||||
|
// ciklusu, pa izmena stupa na snagu bez restarta (od sledećeg ciklusa)
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
sati := 24
|
||||||
|
h.SaBazom(func(db *sql.DB) {
|
||||||
|
sati = procitajIntPodesavanje(db, "backup_interval_sati", 24)
|
||||||
|
})
|
||||||
|
time.Sleep(time.Duration(sati) * time.Hour)
|
||||||
|
h.SaBazom(func(db *sql.DB) {
|
||||||
|
napraviBackup(db, putanjaBaze)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// periodično brisanje isteklih sesija i starih pokušaja prijave
|
||||||
|
go func() {
|
||||||
|
ticker := time.NewTicker(time.Hour)
|
||||||
|
defer ticker.Stop()
|
||||||
|
for range ticker.C {
|
||||||
|
h.SaBazom(func(db *sql.DB) {
|
||||||
|
_ = sqlite.NoviSesijeRepo(db).ObrisiIstekle(context.Background())
|
||||||
|
_ = sqlite.NoviPokusajiPrijaveRepo(db).ObrisiStare(context.Background(), time.Now().Add(-24*time.Hour))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
r.Use(ntechmw.BezbednostHeaders())
|
r.Use(ntechmw.BezbednostHeaders())
|
||||||
r.Use(ntechmw.CsrfMiddleware)
|
r.Use(ntechmw.CsrfMiddleware)
|
||||||
|
|||||||
@@ -57,6 +57,17 @@ func (h *Handler) ZakljucajCitanje(next http.Handler) http.Handler {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SaBazom izvršava fn sa TRENUTNOM konekcijom baze, pod deljenim zaključavanjem.
|
||||||
|
// Namenjeno pozadinskim gorutinama (auto-backup, čišćenje): posle obnove backupa
|
||||||
|
// h.DB se menja, pa gorutine moraju da čitaju aktuelni handle, a ne zatvoreni.
|
||||||
|
// Zaključavanje se drži samo za vreme fn — ne pozivaj iz njega operacije koje
|
||||||
|
// dugo blokiraju (npr. time.Sleep), da ne bi nepotrebno odlagao obnovu.
|
||||||
|
func (h *Handler) SaBazom(fn func(*sql.DB)) {
|
||||||
|
h.mu.RLock()
|
||||||
|
defer h.mu.RUnlock()
|
||||||
|
fn(h.DB)
|
||||||
|
}
|
||||||
|
|
||||||
// Novi kreira novi Handler sa datom bazom.
|
// Novi kreira novi Handler sa datom bazom.
|
||||||
// totpKljuc je 32-bajtni ključ za šifrovanje TOTP tajni u mirovanju.
|
// totpKljuc je 32-bajtni ključ za šifrovanje TOTP tajni u mirovanju.
|
||||||
func Novi(baza *sql.DB, totpKljuc []byte) *Handler {
|
func Novi(baza *sql.DB, totpKljuc []byte) *Handler {
|
||||||
|
|||||||
Reference in New Issue
Block a user