singleflight.go 741 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. package missinggo
  2. import "sync"
  3. type ongoing struct {
  4. do sync.Mutex
  5. users int
  6. }
  7. type SingleFlight struct {
  8. mu sync.Mutex
  9. ongoing map[string]*ongoing
  10. }
  11. type Operation struct {
  12. sf *SingleFlight
  13. id string
  14. }
  15. func (op Operation) Unlock() {
  16. op.sf.Unlock(op.id)
  17. }
  18. func (me *SingleFlight) Lock(id string) Operation {
  19. me.mu.Lock()
  20. on, ok := me.ongoing[id]
  21. if !ok {
  22. on = new(ongoing)
  23. if me.ongoing == nil {
  24. me.ongoing = make(map[string]*ongoing)
  25. }
  26. me.ongoing[id] = on
  27. }
  28. on.users++
  29. me.mu.Unlock()
  30. on.do.Lock()
  31. return Operation{me, id}
  32. }
  33. func (me *SingleFlight) Unlock(id string) {
  34. me.mu.Lock()
  35. on := me.ongoing[id]
  36. on.do.Unlock()
  37. on.users--
  38. if on.users == 0 {
  39. delete(me.ongoing, id)
  40. }
  41. me.mu.Unlock()
  42. }