state.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package file
  2. import (
  3. "time"
  4. "os"
  5. "fmt"
  6. "path/filepath"
  7. "syscall"
  8. )
  9. type State struct {
  10. Source string `json:"source"`
  11. Offset int64 `json:"offset"`
  12. Inode uint64 `json:"inode"`
  13. Fileinfo os.FileInfo `json:"-"` // the file info
  14. Timestamp time.Time `json:"timestamp"`
  15. Finished bool `json:"finished"`
  16. Meta map[string]string `json:"meta"`
  17. TTL time.Duration `json:"ttl"`
  18. }
  19. // NewState creates a new file state
  20. func NewState(fileInfo os.FileInfo, path string) State {
  21. stat := fileInfo.Sys().(*syscall.Stat_t)
  22. return State{
  23. Fileinfo: fileInfo,
  24. Inode: stat.Ino,
  25. Source: path,
  26. Finished: false,
  27. Timestamp: time.Now(),
  28. TTL: -1, // By default, state does have an infinite ttl
  29. Meta: nil,
  30. }
  31. }
  32. func (s *State) ID() uint64 {
  33. return s.Inode
  34. }
  35. // IsEqual compares the state to an other state supporting stringer based on the unique string
  36. func (s *State) IsEqual(c *State) bool {
  37. return s.ID() == c.ID()
  38. }
  39. // IsEmpty returns true if the state is empty
  40. func (s *State) IsEmpty() bool {
  41. return s.Inode == 0 &&
  42. s.Source == "" &&
  43. len(s.Meta) == 0 &&
  44. s.Timestamp.IsZero()
  45. }
  46. func getFileState(path string, info os.FileInfo) (State, error) {
  47. var err error
  48. var absolutePath string
  49. absolutePath, err = filepath.Abs(path)
  50. if err != nil {
  51. return State{}, fmt.Errorf("could not fetch abs path for file %s: %s", absolutePath, err)
  52. }
  53. // Create new state for comparison
  54. newState := NewState(info, absolutePath)
  55. return newState, nil
  56. }