states.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package file
  2. import (
  3. "sync"
  4. "time"
  5. "go-common/library/log"
  6. )
  7. // States handles list of FileState. One must use NewStates to instantiate a
  8. // file states registry. Using the zero-value is not safe.
  9. type States struct {
  10. sync.RWMutex
  11. // states store
  12. states map[uint64]State
  13. }
  14. // NewStates generates a new states registry.
  15. func NewStates() *States {
  16. return &States{
  17. states: map[uint64]State{},
  18. }
  19. }
  20. // Update updates a state. If previous state didn't exist, new one is created
  21. func (s *States) Update(newState State) {
  22. s.Lock()
  23. defer s.Unlock()
  24. id := newState.ID()
  25. if _, ok := s.states[id]; ok {
  26. s.states[id] = newState
  27. return
  28. }
  29. log.V(1).Info("New state added for %s", id)
  30. s.states[id] = newState
  31. }
  32. // Cleanup cleans up the state array. All states which are older then `older` are removed
  33. // The number of states that were cleaned up is returned.
  34. func (s *States) Cleanup() (int) {
  35. s.Lock()
  36. defer s.Unlock()
  37. currentTime := time.Now()
  38. statesBefore := len(s.states)
  39. for inode, state := range s.states {
  40. if state.Finished && state.TTL > 0 && currentTime.Sub(state.Timestamp) > state.TTL {
  41. delete(s.states, inode)
  42. }
  43. }
  44. return statesBefore - len(s.states)
  45. }
  46. // GetStates creates copy of the file states.
  47. func (s *States) GetState(id uint64) State {
  48. s.RLock()
  49. defer s.RUnlock()
  50. if _, ok := s.states[id]; ok {
  51. return s.states[id]
  52. }
  53. return State{}
  54. }
  55. // FindPrevious lookups a registered state, that matching the new state.
  56. // Returns a zero-state if no match is found.
  57. func (s *States) FindPrevious(newState State) State {
  58. s.RLock()
  59. defer s.RUnlock()
  60. if s, ok := s.states[newState.ID()]; ok {
  61. return s
  62. }
  63. return State{}
  64. }
  65. // SetStates overwrites all internal states with the given states array
  66. func (s *States) SetStates(states map[uint64]State) {
  67. s.Lock()
  68. defer s.Unlock()
  69. s.states = states
  70. }
  71. // UpdateWithTs updates a state, assigning the given timestamp.
  72. // If previous state didn't exist, new one is created
  73. func (s *States) UpdateWithTs(newState State, ts time.Time) {
  74. id := newState.ID()
  75. oldState := s.FindPrevious(newState)
  76. newState.Timestamp = ts
  77. s.Lock()
  78. defer s.Unlock()
  79. s.states[id] = newState
  80. if oldState.IsEmpty() {
  81. log.V(1).Info("New state added for %s", newState.Source)
  82. }
  83. }