Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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!)



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




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: