From 0aee714f3941173893b42c5f0880b7cb6b592548 Mon Sep 17 00:00:00 2001 From: siddharth ravikumar Date: Sun, 25 Dec 2022 12:20:17 -0500 Subject: db: fix data race - Use a sync.RWMutex for mutex locks. - Use sync.RWMutex.RLock when reading from the downloaded map. - Use sync.RWMutex.Lock when writing to the downloaded map. --- db/db_test.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'db/db_test.go') diff --git a/db/db_test.go b/db/db_test.go index de27149..966ce85 100644 --- a/db/db_test.go +++ b/db/db_test.go @@ -4,6 +4,7 @@ package db import ( + "fmt" "os" "path" "testing" @@ -370,3 +371,49 @@ func TestWriteExistingDB(t *testing.T) { return } } + +func TestConcurrentWrites(t *testing.T) { + dbPath = path.Join(os.TempDir(), "fern-db.json") + defer os.Remove(dbPath) + defer resetDBPath() + + db, err := Open() + if err != nil { + t.Errorf("db open failed: %v", err) + return + } + + // Randomly create a some entries. + numEntries := 1000 + entries := make([]string, 0) + for i := 0; i < numEntries; i++ { + entries = append(entries, fmt.Sprintf("entry-%d", i)) + } + + // Go routine for adding entries to the db. + addEntries := func(db *FernDB, feed string, entries []string, donec chan int) { + for _, entry := range entries { + db.Add(feed, entry) + } + donec <- 1 + } + + // Concurrently write entries to a feed. + donec := make(chan int) + feed := "npr" + routines := 5 + for i := 0; i < routines; i++ { + go addEntries(db, feed, entries, donec) + } + routinesDone := 0 + for routinesDone != routines { + <-donec + routinesDone += 1 + } + + // Check if there are exactly numEntries entries. + if len(db.downloaded[feed]) != numEntries { + t.Errorf("downloaded entries != %d: %v", + numEntries, db.downloaded[feed]) + } +} -- cgit v1.2.3