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  }