04/demos/07_select_statements/after/main.go
unknown
golang
4 years ago
2.2 kB
12
Indexable
package main import ( "fmt" "math/rand" "sync" "time" ) var cache = map[int]Book{} var rnd = rand.New(rand.NewSource(time.Now().UnixNano())) func main() { wg := &sync.WaitGroup{} m := &sync.RWMutex{} cacheCh := make(chan Book) dbCh := make(chan Book) for i := 0; i < 10; i++ { id := rnd.Intn(10) + 1 wg.Add(2) go func(id int, wg *sync.WaitGroup, m *sync.RWMutex, ch chan<- Book) { if b, ok := queryCache(id, m); ok { ch <- b } wg.Done() }(id, wg, m, cacheCh) go func(id int, wg *sync.WaitGroup, m *sync.RWMutex, ch chan<- Book) { if b, ok := queryDatabase(id); ok { m.Lock() cache[id] = b m.Unlock() ch <- b } wg.Done() }(id, wg, m, dbCh) wg.Add(1) go func(cacheCh, dbCh <-chan Book) { defer wg.Done() select { case b := <-cacheCh: fmt.Println("from cache") fmt.Println(b) <-dbCh case b := <-dbCh: fmt.Println("from database") fmt.Println(b) } }(cacheCh, dbCh) } wg.Wait() } func queryCache(id int, m *sync.RWMutex) (Book, bool) { m.RLock() b, ok := cache[id] m.RUnlock() return b, ok } func queryDatabase(id int) (Book, bool) { time.Sleep(100 * time.Millisecond) for _, b := range books { if b.ID == id { return b, true } } return Book{}, false }
Editor is loading...