online_map.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  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. if ip == "127.0.0.1" {
  33. return
  34. }
  35. c.access.Lock()
  36. defer c.access.Unlock()
  37. if _, ok := c.ipList[ip]; !ok {
  38. c.ipList[ip] = time.Now()
  39. }
  40. if time.Since(c.lastCleanup) > c.cleanupPeriod {
  41. now := time.Now()
  42. for k, t := range c.ipList {
  43. diff := now.Sub(t)
  44. if diff.Seconds() > 20 {
  45. delete(c.ipList, k) // safe to do delete in range
  46. }
  47. }
  48. c.lastCleanup = time.Now()
  49. }
  50. c.value = len(c.ipList)
  51. }
  52. func (c *OnlineMap) GetKeys() []string {
  53. c.access.Lock()
  54. defer c.access.Unlock()
  55. keys := []string{}
  56. for k := range c.ipList {
  57. keys = append(keys, k)
  58. }
  59. return keys
  60. }