github.com/Cloud-Foundations/Dominator@v0.3.4/sub/rpcd/lib.go (about) 1 package rpcd 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 "time" 8 9 "github.com/Cloud-Foundations/Dominator/lib/constants" 10 "github.com/Cloud-Foundations/Dominator/lib/srpc" 11 ) 12 13 const ( 14 maximumClientLockDuration = 15 * time.Second 15 ) 16 17 func readImageFile(filename string) string { 18 if file, err := os.Open(filename); err != nil { 19 return "" 20 } else { 21 defer file.Close() 22 var imageName string 23 num, err := fmt.Fscanf(file, "%s", &imageName) 24 if err == nil && num == 1 { 25 return imageName 26 } 27 return "" 28 } 29 } 30 31 func readInitialImageFile() string { 32 return readImageFile(constants.InitialImageNameFile) 33 } 34 35 func readPatchedImageFile() string { 36 return readImageFile(constants.PatchedImageNameFile) 37 } 38 39 // Check if another client has the client lock. The object lock must be 40 // held. Returns an error if another client has the lock. 41 func (t *rpcType) checkIfLockedByAnotherClient(conn *srpc.Conn) error { 42 if t.lockedBy == nil { 43 if !t.lockedUntil.IsZero() { 44 t.lockedUntil = time.Time{} 45 } 46 return nil 47 } 48 if time.Since(t.lockedUntil) >= 0 { 49 t.lockedBy = nil 50 t.lockedUntil = time.Time{} 51 return nil 52 } 53 if t.lockedBy == conn { 54 return nil 55 } 56 return errors.New("another client has the lock") 57 } 58 59 // Try to grab the client lock. The object lock must be held. If duration is 60 // zero or less, only a check is performed. 61 // Returns an error if another client has the lock. 62 func (t *rpcType) getClientLock(conn *srpc.Conn, duration time.Duration) error { 63 if err := t.checkIfLockedByAnotherClient(conn); err != nil { 64 return err 65 } 66 if duration <= 0 { 67 return nil 68 } 69 t.lockedBy = conn 70 if duration > maximumClientLockDuration { 71 duration = maximumClientLockDuration 72 } 73 t.lockedUntil = time.Now().Add(duration) 74 return nil 75 }