Permalink
Browse files

Don't do more than one bg fetch for the same blob

Closes #120
  • Loading branch information...
1 parent c1a8847 commit fb8d696cc090e2c4ee6fa4623b00ac84f744fa3b @dustin dustin committed Feb 16, 2013
Showing with 81 additions and 1 deletion.
  1. +9 −1 blobs.go
  2. +37 −0 namedlock.go
  3. +35 −0 namedlock_test.go
View
@@ -444,6 +444,8 @@ func hasBlob(oid string) bool {
return err == nil
}
+var fetchLocks namedLock
+
func performFetch(oid, prev string) {
c := captureResponseWriter{w: ioutil.Discard}
@@ -458,7 +460,13 @@ func performFetch(oid, prev string) {
return
}
- err = getBlobFromRemote(&c, oid, http.Header{}, 100)
+ if fetchLocks.Lock(oid) {
+ defer fetchLocks.Unlock(oid)
+ err = getBlobFromRemote(&c, oid, http.Header{}, 100)
+ } else {
+ log.Printf("Not fetching remote, already in progress.")
+ return
+ }
if err == nil && c.statusCode == 200 {
if prev != "" {
View
@@ -0,0 +1,37 @@
+package main
+
+import (
+ "sync"
+)
+
+type namedLock struct {
+ locks map[string]bool
+ mutex sync.Mutex
+}
+
+// Acquire a lock by name, returns true if acquired.
+func (nl *namedLock) Lock(s string) bool {
+ nl.mutex.Lock()
+ defer nl.mutex.Unlock()
+
+ if nl.locks == nil {
+ nl.locks = map[string]bool{}
+ }
+
+ held := nl.locks[s]
+ if !held {
+ nl.locks[s] = true
+ }
+ return !held
+}
+
+func (nl *namedLock) Unlock(s string) {
+ nl.mutex.Lock()
+ defer nl.mutex.Unlock()
+
+ if !nl.locks[s] {
+ panic(s + " was not held")
+ }
+
+ delete(nl.locks, s)
+}
View
@@ -0,0 +1,35 @@
+package main
+
+import (
+ "testing"
+)
+
+func TestNamedLock(t *testing.T) {
+ nl := namedLock{}
+
+ if nl.Lock("t1") == false {
+ t.Fatalf("Expected initial lock to succeed")
+ }
+
+ if nl.Lock("t1") == true {
+ t.Fatalf("Expected subsequent lock to fail")
+ }
+
+ if nl.Lock("t2") == false {
+ t.Fatalf("Expected initial lock (2) to succeed")
+ }
+
+ if nl.Lock("t2") == true {
+ t.Fatalf("Expected subsequent lock (2) to fail")
+ }
+
+ nl.Unlock("t1")
+ nl.Unlock("t2")
+
+ defer func() {
+ if x := recover(); x == nil {
+ t.Fatalf("Expected panic on double free")
+ }
+ }()
+ nl.Unlock("t1")
+}

0 comments on commit fb8d696

Please sign in to comment.