4 ms·
Nice article! This is an interesting approach, much less likely to make Go devs' blood boil over unnecessary libraries. My only question is why the server / HT
by samuelroth 6y ago
Nice article! This is an interesting approach, much less likely to make Go devs' blood boil over unnecessary libraries.
My only question is why the server / HTTP handlers have to deal with the Mutex. That seems like a "leak" from the `TaskStore` abstraction, which otherwise I really like. (Thank you for not using channels in that interface!)
- jrockway 6y agoI think it's necessary to leak the details of the mutex until you have some sort of transaction object to abstract that away. In a concurrent workload, these two things are different: store.Lock() store.WriteKey("foo", "bar") x := store.ReadKey("foo") store.Unlock() // x is always "bar" And: store.Lock() store.WriteKey("foo", "bar") store.Unlock() store.Lock() x := store.ReadKey("foo") store.Unlock() // x could be whatever another goroutine set "foo" to, not the "bar" that you just wrote. In a more complicated app, you'll have library that acts as the datastore, with transaction objects that abstract away the actual mutex (which will be something more complicated): var x string err := db.DoTx(func(tx *Tx) { tx.Write("foo", "bar") x = tx.Read("foo") }) if err != nil { ... } // what x is depends on the details of your database; maybe you're running at "read uncommitted", maybe you're running at "serializable". But, even in the simple examples, it's worth thinking about the difference between lock { write; read } and lock { write }; lock { read }.