Skip to content

Commit acd5acf

Browse files
authored
pref: cache locale resources on first load (#320)
1 parent dc2e1f6 commit acd5acf

File tree

1 file changed

+31
-7
lines changed

1 file changed

+31
-7
lines changed

language.go

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@ import (
1212
//go:embed lang
1313
var fs embed.FS
1414

15+
// localeCache stores parsed locale resources keyed by the embedded file path.
16+
var localeCache sync.Map
17+
18+
// localeEntry caches the parsed resources of a locale file.
19+
type localeEntry struct {
20+
once sync.Once
21+
resources map[string]string
22+
err error
23+
}
24+
1525
// Language defines a Language struct.
1626
type Language struct {
1727
dir string
@@ -68,20 +78,34 @@ func (lang *Language) SetLocale(locale string) *Language {
6878
}
6979

7080
fileName := fmt.Sprintf("%s/%s.json", lang.dir, locale)
71-
bs, err := fs.ReadFile(fileName)
72-
if err != nil {
73-
lang.Error = fmt.Errorf("%w: %w", ErrNotExistLocale(fileName), err)
81+
entryIface, _ := localeCache.LoadOrStore(fileName, new(localeEntry))
82+
entry := entryIface.(*localeEntry)
83+
84+
entry.once.Do(func() {
85+
bs, err := fs.ReadFile(fileName)
86+
if err != nil {
87+
entry.err = fmt.Errorf("%w: %w", ErrNotExistLocale(fileName), err)
88+
return
89+
}
90+
91+
var resources map[string]string
92+
if err := json.Unmarshal(bs, &resources); err != nil {
93+
entry.err = fmt.Errorf("failed to decode locale file %q: %w", fileName, err)
94+
return
95+
}
96+
entry.resources = resources
97+
})
98+
99+
if entry.err != nil {
100+
lang.Error = entry.err
74101
return lang
75102
}
76103

77-
var resources map[string]string
78-
_ = json.Unmarshal(bs, &resources)
79-
80104
lang.rw.Lock()
81105
defer lang.rw.Unlock()
82106

83107
lang.locale = locale
84-
lang.resources = resources
108+
lang.resources = entry.resources
85109
return lang
86110
}
87111

0 commit comments

Comments
 (0)