Merge grane feature/backup-gorutine-svez-db: pozadinske gorutine koriste svežu konekciju

This commit is contained in:
2026-06-12 21:56:28 +02:00
2 changed files with 41 additions and 22 deletions
+30 -22
View File
@@ -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)
+11
View File
@@ -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 {