Hacker News new | ask | show | jobs
by samuelroth 1985 days 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!)

1 comments

I 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 }.