problem: Store both an IP address as well as a time to a counter. something like this
ip, time, count
and then i would like to be able to increment the count for each ip:
ip++
in my map, and then on a given interval, i would like to iterate all keys and find the keys with a time stamp older than N minutes.
I need this to make sure i don't "forget" a key in memory if for some reason, client disconnect and i dont delete the key properly.
http://play.golang.org/p/RiWWOCARq7
Question: How do i add a time stamp to every IP address i store in my map. Also i need this be be used across multiple go routines
Im new to both programming and Golang, so if this is not even the correct approach, if anyone could point me in the right direction, i would appreciate it.
For example,
package main
import (
"sync"
"time"
)
type IPCounter struct {
IPAddr string
Time time.Time
Count int
}
type ipCounterMap struct {
counters map[string]IPCounter
mutex sync.RWMutex
}
var ipCounters = ipCounterMap{counters: make(map[string]IPCounter)}
// Get IP address counter
func Counter(ipAddr string) IPCounter {
ipCounters.mutex.RLock()
defer ipCounters.mutex.RUnlock()
counter, found := ipCounters.counters[ipAddr]
if !found {
counter.IPAddr = ipAddr
}
return counter
}
// Increment IP address counter
func Incr(ipAddr string) {
now := time.Now().UTC()
ipCounters.mutex.Lock()
defer ipCounters.mutex.Unlock()
counter, found := ipCounters.counters[ipAddr]
if !found {
counter.IPAddr = ipAddr
}
counter.Time = now
counter.Count++
ipCounters.counters[ipAddr] = counter
}
// Delete IP address counter
func Delete(ipAddr string) {
ipCounters.mutex.Lock()
defer ipCounters.mutex.Unlock()
delete(ipCounters.counters, ipAddr)
}
// Get old IP address counters old durations ago
func OldIPCounters(old time.Duration) []IPCounter {
var counters []IPCounter
oldTime := time.Now().UTC().Add(-old)
ipCounters.mutex.RLock()
defer ipCounters.mutex.RUnlock()
for _, counter := range ipCounters.counters {
if counter.Time.Before(oldTime) {
counters = append(counters, counter)
}
}
return counters
}
func main() {}
You probably want a map of ip -> struct { ip, counter, lastTime } that way, you can look up the counter by ip and then update it
var Counters = map[string]*Counter{}
type Counter struct {
ip string
count int
lastTime time.Time
}
Here's a working example on Play http://play.golang.org/p/TlCTc_4iq5
Adding the find older than is simply range over the values of the map comparing to now and do something when it's old enough.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With