device.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // Copyright (C) 2014 The Syncthing Authors.
  2. //
  3. // This program is free software: you can redistribute it and/or modify it
  4. // under the terms of the GNU General Public License as published by the Free
  5. // Software Foundation, either version 3 of the License, or (at your option)
  6. // any later version.
  7. //
  8. // This program is distributed in the hope that it will be useful, but WITHOUT
  9. // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  11. // more details.
  12. //
  13. // You should have received a copy of the GNU General Public License along
  14. // with this program. If not, see <http://www.gnu.org/licenses/>.
  15. package stats
  16. import (
  17. "time"
  18. "github.com/syncthing/syncthing/internal/protocol"
  19. "github.com/syndtr/goleveldb/leveldb"
  20. )
  21. const (
  22. deviceStatisticTypeLastSeen = iota
  23. )
  24. var deviceStatisticsTypes = []byte{
  25. deviceStatisticTypeLastSeen,
  26. }
  27. type DeviceStatistics struct {
  28. LastSeen time.Time
  29. }
  30. type DeviceStatisticsReference struct {
  31. db *leveldb.DB
  32. device protocol.DeviceID
  33. }
  34. func NewDeviceStatisticsReference(db *leveldb.DB, device protocol.DeviceID) *DeviceStatisticsReference {
  35. return &DeviceStatisticsReference{
  36. db: db,
  37. device: device,
  38. }
  39. }
  40. func (s *DeviceStatisticsReference) key(stat byte) []byte {
  41. k := make([]byte, 1+1+32)
  42. k[0] = keyTypeDeviceStatistic
  43. k[1] = stat
  44. copy(k[1+1:], s.device[:])
  45. return k
  46. }
  47. func (s *DeviceStatisticsReference) GetLastSeen() time.Time {
  48. value, err := s.db.Get(s.key(deviceStatisticTypeLastSeen), nil)
  49. if err != nil {
  50. if err != leveldb.ErrNotFound {
  51. l.Warnln("DeviceStatisticsReference: Failed loading last seen value for", s.device, ":", err)
  52. }
  53. return time.Unix(0, 0)
  54. }
  55. rtime := time.Time{}
  56. err = rtime.UnmarshalBinary(value)
  57. if err != nil {
  58. l.Warnln("DeviceStatisticsReference: Failed parsing last seen value for", s.device, ":", err)
  59. return time.Unix(0, 0)
  60. }
  61. if debug {
  62. l.Debugln("stats.DeviceStatisticsReference.GetLastSeen:", s.device, rtime)
  63. }
  64. return rtime
  65. }
  66. func (s *DeviceStatisticsReference) WasSeen() {
  67. if debug {
  68. l.Debugln("stats.DeviceStatisticsReference.WasSeen:", s.device)
  69. }
  70. value, err := time.Now().MarshalBinary()
  71. if err != nil {
  72. l.Warnln("DeviceStatisticsReference: Failed serializing last seen value for", s.device, ":", err)
  73. return
  74. }
  75. err = s.db.Put(s.key(deviceStatisticTypeLastSeen), value, nil)
  76. if err != nil {
  77. l.Warnln("Failed serializing last seen value for", s.device, ":", err)
  78. }
  79. }
  80. // Never called, maybe because it's worth while to keep the data
  81. // or maybe because we have no easy way of knowing that a device has been removed.
  82. func (s *DeviceStatisticsReference) Delete() error {
  83. for _, stype := range deviceStatisticsTypes {
  84. err := s.db.Delete(s.key(stype), nil)
  85. if debug && err == nil {
  86. l.Debugln("stats.DeviceStatisticsReference.Delete:", s.device, stype)
  87. }
  88. if err != nil && err != leveldb.ErrNotFound {
  89. return err
  90. }
  91. }
  92. return nil
  93. }
  94. func (s *DeviceStatisticsReference) GetStatistics() DeviceStatistics {
  95. return DeviceStatistics{
  96. LastSeen: s.GetLastSeen(),
  97. }
  98. }