Problem: block repo did not serialize writes

Solution: serialize writes
This commit is contained in:
Peter Stuifzand 2022-05-26 21:17:51 +02:00
parent 1acd0e5f0f
commit 19183da0f8
2 changed files with 39 additions and 10 deletions

View File

@ -25,23 +25,56 @@ import (
) )
type BlockRepository interface { type BlockRepository interface {
Save(block Block) error Save(id string, block Block) error
Load(id string) (Block, error) Load(id string) (Block, error)
} }
type blockSaveMessage struct {
id string
block Block
}
type blockRepo struct { type blockRepo struct {
dirname string dirname string
saveC chan blockSaveMessage
errC chan error
} }
func (br *blockRepo) Save(id string, block Block) error { func saveBlock(dirname, id string, block Block) error {
f, err := os.OpenFile(filepath.Join(br.dirname, BlocksDirectory, id), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) f, err := os.OpenFile(filepath.Join(dirname, BlocksDirectory, id), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
defer f.Close()
if err != nil { if err != nil {
return err return err
} }
defer f.Close()
enc := json.NewEncoder(f) enc := json.NewEncoder(f)
enc.SetIndent("", " ") enc.SetIndent("", " ")
return enc.Encode(&block) err = enc.Encode(&block)
if err != nil {
return err
}
return nil
}
func NewBlockRepo(dirname string) BlockRepository {
saveC := make(chan blockSaveMessage, 1)
errC := make(chan error)
go func() {
for msg := range saveC {
err := saveBlock(dirname, msg.id, msg.block)
errC <- err
}
}()
return &blockRepo{
dirname: dirname,
saveC: saveC,
errC: errC,
}
}
func (br *blockRepo) Save(id string, block Block) error {
br.saveC <- blockSaveMessage{id, block}
err := <-br.errC
return err
} }
func (br *blockRepo) Load(id string) (Block, error) { func (br *blockRepo) Load(id string) (Block, error) {

View File

@ -1064,6 +1064,7 @@ func main() {
} }
mp = NewFilePages(dataDir, searchIndex) mp = NewFilePages(dataDir, searchIndex)
repo := NewBlockRepo("data")
http.Handle("/auth/", &authHandler{}) http.Handle("/auth/", &authHandler{})
http.HandleFunc("/api/block/view", wrapAuth(func(w http.ResponseWriter, r *http.Request) { http.HandleFunc("/api/block/view", wrapAuth(func(w http.ResponseWriter, r *http.Request) {
@ -1081,7 +1082,6 @@ func main() {
id := r.URL.Query().Get("id") id := r.URL.Query().Get("id")
repo := blockRepo{dirname: "data"}
block, err := repo.Load(id) block, err := repo.Load(id)
if err != nil { if err != nil {
http.Error(w, err.Error(), 500) http.Error(w, err.Error(), 500)
@ -1165,7 +1165,6 @@ func main() {
http.Error(w, "missing id", 400) http.Error(w, "missing id", 400)
return return
} }
repo := blockRepo{dirname: "data"}
block, err := repo.Load(id) block, err := repo.Load(id)
block.Text = r.Form.Get("text") block.Text = r.Form.Get("text")
err = repo.Save(id, block) err = repo.Save(id, block)
@ -1196,9 +1195,6 @@ func main() {
http.Error(w, "missing id", 400) http.Error(w, "missing id", 400)
return return
} }
repo := blockRepo{
dirname: "data",
}
newBlock := Block{ newBlock := Block{
Text: r.Form.Get("text"), Text: r.Form.Get("text"),
Children: []string{}, Children: []string{},