forked from tangled.org/core
Monorepo for Tangled

appview/pages: fix concurrent write in dev mode

When in dev mode. Concurrent writes to the template map will cause a
concurrent write panic and crash appview. Quickly moving between pages
can trigger this crash. This is addressed by adding a RWMutex on the
templates. RWMutex allows multiple readers, but only one writer.

Signed-off-by: Ciel <jamie@longest.voyage>

authored by ok-ciel.bsky.social and committed by Tangled d876b982 ba66e0a1

Changed files
+11 -1
appview
pages
+11 -1
appview/pages/pages.go
··· 14 14 "os" 15 15 "path/filepath" 16 16 "strings" 17 + "sync" 17 18 18 19 "tangled.sh/tangled.sh/core/appview/commitverify" 19 20 "tangled.sh/tangled.sh/core/appview/config" ··· 39 40 var Files embed.FS 40 41 41 42 type Pages struct { 42 - t map[string]*template.Template 43 + mu sync.RWMutex 44 + t map[string]*template.Template 45 + 43 46 avatar config.AvatarConfig 44 47 dev bool 45 48 embedFS embed.FS ··· 56 59 } 57 60 58 61 p := &Pages{ 62 + mu: sync.RWMutex{}, 59 63 t: make(map[string]*template.Template), 60 64 dev: config.Core.Dev, 61 65 avatar: config.Avatar, ··· 147 151 } 148 152 149 153 log.Printf("total templates loaded: %d", len(templates)) 154 + p.mu.Lock() 155 + defer p.mu.Unlock() 150 156 p.t = templates 151 157 } 152 158 ··· 207 213 } 208 214 209 215 // Update the template in the map 216 + p.mu.Lock() 217 + defer p.mu.Unlock() 210 218 p.t[name] = tmpl 211 219 log.Printf("template reloaded from disk: %s", name) 212 220 return nil ··· 221 229 } 222 230 } 223 231 232 + p.mu.RLock() 233 + defer p.mu.RUnlock() 224 234 tmpl, exists := p.t[templateName] 225 235 if !exists { 226 236 return fmt.Errorf("template not found: %s", templateName)