github.com/Cloud-Foundations/Dominator@v0.3.4/sub/rpcd/poll.go (about)

     1  package rpcd
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"syscall"
     7  	"time"
     8  
     9  	"github.com/Cloud-Foundations/Dominator/lib/srpc"
    10  	"github.com/Cloud-Foundations/Dominator/proto/sub"
    11  )
    12  
    13  var (
    14  	filename  string    = "/proc/uptime"
    15  	startTime time.Time = time.Now()
    16  )
    17  
    18  func (t *rpcType) Poll(conn *srpc.Conn) error {
    19  	defer conn.Flush()
    20  	var request sub.PollRequest
    21  	var response sub.PollResponse
    22  	if err := conn.Decode(&request); err != nil {
    23  		_, err = conn.WriteString(err.Error() + "\n")
    24  		return err
    25  	}
    26  	if !request.ShortPollOnly && !conn.GetAuthInformation().HaveMethodAccess {
    27  		_, e := conn.WriteString(srpc.ErrorAccessToMethodDenied.Error() + "\n")
    28  		return e
    29  	}
    30  	if _, err := conn.WriteString("\n"); err != nil {
    31  		return err
    32  	}
    33  	response.NetworkSpeed = t.params.NetworkReaderContext.MaximumSpeed()
    34  	response.CurrentConfiguration = t.getConfiguration()
    35  	t.rwLock.RLock()
    36  	response.FetchInProgress = t.fetchInProgress
    37  	response.UpdateInProgress = t.updateInProgress
    38  	if t.lastFetchError != nil {
    39  		response.LastFetchError = t.lastFetchError.Error()
    40  	}
    41  	if !t.updateInProgress {
    42  		if t.lastUpdateError != nil {
    43  			response.LastUpdateError = t.lastUpdateError.Error()
    44  		}
    45  		response.LastUpdateHadTriggerFailures = t.lastUpdateHadTriggerFailures
    46  	}
    47  	response.InitialImageName = t.initialImageName
    48  	response.LastSuccessfulImageName = t.lastSuccessfulImageName
    49  	response.LastNote = t.lastNote
    50  	response.LastWriteError = t.lastWriteError
    51  	response.LockedByAnotherClient =
    52  		t.getClientLock(conn, request.LockFor) != nil
    53  	response.LockedUntil = t.lockedUntil
    54  	response.FreeSpace = t.getFreeSpace()
    55  	response.DisruptionState = t.disruptionState
    56  	t.rwLock.RUnlock()
    57  	response.StartTime = startTime
    58  	response.PollTime = time.Now()
    59  	response.ScanCount = t.params.FileSystemHistory.ScanCount()
    60  	response.DurationOfLastScan =
    61  		t.params.FileSystemHistory.DurationOfLastScan()
    62  	response.GenerationCount = t.params.FileSystemHistory.GenerationCount()
    63  	response.SystemUptime = t.getSystemUptime()
    64  	fs := t.params.FileSystemHistory.FileSystem()
    65  	if fs != nil &&
    66  		!request.ShortPollOnly &&
    67  		request.HaveGeneration != t.params.FileSystemHistory.GenerationCount() {
    68  		response.FileSystemFollows = true
    69  	}
    70  	if err := conn.Encode(response); err != nil {
    71  		return err
    72  	}
    73  	if response.FileSystemFollows {
    74  		if err := fs.FileSystem.Encode(conn); err != nil {
    75  			return err
    76  		}
    77  		if err := fs.ObjectCache.Encode(conn); err != nil {
    78  			return err
    79  		}
    80  	}
    81  	return nil
    82  }
    83  
    84  func (t *rpcType) getFreeSpace() *uint64 {
    85  	rootDir := t.config.RootDirectoryName
    86  	if fd, err := syscall.Open(rootDir, syscall.O_RDONLY, 0); err != nil {
    87  		t.params.Logger.Printf("error opening: %s: %s", rootDir, err)
    88  		return nil
    89  	} else {
    90  		defer syscall.Close(fd)
    91  		var statbuf syscall.Statfs_t
    92  		if err := syscall.Fstatfs(fd, &statbuf); err != nil {
    93  			t.params.Logger.Printf("error getting file-system stats: %s\n", err)
    94  			return nil
    95  		}
    96  		retval := uint64(statbuf.Bfree * uint64(statbuf.Bsize))
    97  		return &retval
    98  	}
    99  }
   100  
   101  func (t *rpcType) getSystemUptime() *time.Duration {
   102  	if uptime, err := getSystemUptime(); err != nil {
   103  		t.params.Logger.Printf("error getting system uptime: %s\n", err)
   104  		return nil
   105  	} else {
   106  		return &uptime
   107  	}
   108  }
   109  
   110  func getSystemUptime() (time.Duration, error) {
   111  	file, err := os.Open(filename)
   112  	if err != nil {
   113  		return 0, err
   114  	}
   115  	defer file.Close()
   116  	var idleTime, upTime float64
   117  	nScanned, err := fmt.Fscanf(file, "%f %f", &upTime, &idleTime)
   118  	if err != nil {
   119  		return 0, err
   120  	}
   121  	if nScanned < 2 {
   122  		return 0, fmt.Errorf("only read %d values from %s", nScanned, filename)
   123  	}
   124  	return time.Duration(upTime * float64(time.Second)), nil
   125  }