online_map.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package stats
  2. import (
  3. "sync"
  4. "time"
  5. )
  6. // OnlineMap is an implementation of stats.OnlineMap.
  7. type OnlineMap struct {
  8. value int
  9. ipList map[string]time.Time
  10. access sync.RWMutex
  11. lastCleanup time.Time
  12. cleanupPeriod time.Duration
  13. }
  14. // NewOnlineMap creates a new instance of OnlineMap.
  15. func NewOnlineMap() *OnlineMap {
  16. return &OnlineMap{
  17. ipList: make(map[string]time.Time),
  18. lastCleanup: time.Now(),
  19. cleanupPeriod: 10 * time.Second,
  20. }
  21. }
  22. // Count implements stats.OnlineMap.
  23. func (c *OnlineMap) Count() int {
  24. return c.value
  25. }
  26. // List implements stats.OnlineMap.
  27. func (c *OnlineMap) List() []string {
  28. return c.GetKeys()
  29. }
  30. // AddIP implements stats.OnlineMap.
  31. func (c *OnlineMap) AddIP(ip string) {
  32. list := c.ipList
  33. if ip == "127.0.0.1" {
  34. return
  35. }
  36. if _, ok := list[ip]; !ok {
  37. c.access.Lock()
  38. list[ip] = time.Now()
  39. c.access.Unlock()
  40. }
  41. if time.Since(c.lastCleanup) > c.cleanupPeriod {
  42. list = c.RemoveExpiredIPs(list)
  43. c.lastCleanup = time.Now()
  44. }
  45. c.value = len(list)
  46. c.ipList = list
  47. }
  48. func (c *OnlineMap) GetKeys() []string {
  49. c.access.RLock()
  50. defer c.access.RUnlock()
  51. keys := []string{}
  52. for k := range c.ipList {
  53. keys = append(keys, k)
  54. }
  55. return keys
  56. }
  57. func (c *OnlineMap) RemoveExpiredIPs(list map[string]time.Time) map[string]time.Time {
  58. c.access.Lock()
  59. defer c.access.Unlock()
  60. now := time.Now()
  61. for k, t := range list {
  62. diff := now.Sub(t)
  63. if diff.Seconds() > 20 {
  64. delete(list, k)
  65. }
  66. }
  67. return list
  68. }
  69. func (c *OnlineMap) IpTimeMap() map[string]time.Time {
  70. list := c.ipList
  71. if time.Since(c.lastCleanup) > c.cleanupPeriod {
  72. list = c.RemoveExpiredIPs(list)
  73. c.lastCleanup = time.Now()
  74. }
  75. return c.ipList
  76. }