Skip to content

Commit a0c9fce

Browse files
committed
Dictionary auto-save
1 parent 7b81bf1 commit a0c9fce

2 files changed

Lines changed: 64 additions & 1 deletion

File tree

cmd/web/main.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ func main() {
4242
os.Exit(1)
4343
}
4444

45+
defer registry.SaveAll(ctx)
46+
4547
server := server.NewServer(ctx, registry)
4648

4749
addr := defaultServerAddr
@@ -93,5 +95,24 @@ func initRegistry(ctx context.Context) (*spellchecker.Registry, error) {
9395
return nil, fmt.Errorf("unable to create dir %s: %w", dir, err)
9496
}
9597

96-
return spellchecker.NewRegistry(ctx, dir)
98+
var saveInterval time.Duration
99+
100+
saveIntervalStr := os.Getenv("SPELLCHECKER_AUTOSAVE_INTERVAL")
101+
if saveIntervalStr != "" {
102+
i, err := time.ParseDuration(saveIntervalStr)
103+
if err != nil {
104+
return nil, fmt.Errorf("invalid SPELLCHECKER_AUTOSAVE_INTERVAL: %w", err)
105+
}
106+
107+
saveInterval = i
108+
}
109+
110+
result, err := spellchecker.NewRegistry(ctx, dir)
111+
if err != nil {
112+
return nil, err
113+
}
114+
115+
result.AutoSave(ctx, saveInterval)
116+
117+
return result, nil
97118
}

internal/spellchecker/registry.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"path"
1010
"strings"
1111
"sync"
12+
"time"
1213

1314
"github.com/f1monkey/spellchecker"
1415
"github.com/f1monkey/spellchecker-web/internal/logger"
@@ -64,6 +65,28 @@ func NewRegistry(ctx context.Context, dir string) (*Registry, error) {
6465
}, nil
6566
}
6667

68+
func (r *Registry) AutoSave(ctx context.Context, interval time.Duration) {
69+
if interval <= 0 {
70+
return
71+
}
72+
73+
go func() {
74+
ticker := time.NewTicker(interval)
75+
defer ticker.Stop()
76+
77+
for {
78+
select {
79+
case <-ctx.Done():
80+
return
81+
case <-ticker.C:
82+
if err := r.SaveAll(ctx); err != nil {
83+
logger.FromContext(ctx).Error("registry: save all error", "error", err)
84+
}
85+
}
86+
}
87+
}()
88+
}
89+
6790
func (r *Registry) Add(code string, options Options) (*spellchecker.Spellchecker, error) {
6891
r.mu.Lock()
6992
defer r.mu.Unlock()
@@ -113,10 +136,29 @@ func (r *Registry) Delete(code string) error {
113136
return nil
114137
}
115138

139+
func (r *Registry) SaveAll(ctx context.Context) error {
140+
r.mu.RLock()
141+
defer r.mu.RUnlock()
142+
143+
for code := range r.items {
144+
if err := r.doSave(code); err != nil {
145+
return err
146+
}
147+
148+
logger.FromContext(ctx).Info("registry: dictionary saved", "dictionary", code)
149+
}
150+
151+
return nil
152+
}
153+
116154
func (r *Registry) Save(code string) error {
117155
r.mu.RLock()
118156
defer r.mu.RUnlock()
119157

158+
return r.doSave(code)
159+
}
160+
161+
func (r *Registry) doSave(code string) error {
120162
item, ok := r.items[code]
121163
if !ok {
122164
return ErrNotFound

0 commit comments

Comments
 (0)