Created
July 11, 2024 20:01
-
-
Save podikoglou/4fb70f18cd29593e837c2c0f6e5c5f9c to your computer and use it in GitHub Desktop.
I really like this piece of code but I realised it's useless
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package engine | |
import ( | |
"sync/atomic" | |
"time" | |
"github.com/emirpasic/gods/maps/hashmap" | |
) | |
const ( | |
metricsInterval = 3 * time.Minute | |
topKeysCount = 10 | |
) | |
type Metrics struct { | |
// This channel receives messages (the content being a key name) from the request | |
// handler when a key is read. | |
getChan chan string | |
// This channel receives messages (the content being a key name) from the request | |
// handler when a key is written to. | |
putChan chan string | |
// This map associates key names with a number, which is the amount of reads that | |
// have happened in the past few minutes. | |
getMetrics *hashmap.Map | |
// This map associates key names with a number, which is the amount of writes that | |
// have happened in the past few minutes. | |
putMetrics *hashmap.Map | |
} | |
// Creates a new metrics object which initializes the channels and the different metrics. | |
func NewMetrics() *Metrics { | |
return &Metrics{getChan: make(chan string, 64), putChan: make(chan string, 64), getMetrics: hashmap.New(), putMetrics: hashmap.New()} | |
} | |
// Takes care of destroying the channels so we don't have any memory leaks or whatever. | |
func (m *Metrics) DestroyMetrics() { | |
close(m.getChan) | |
close(m.putChan) | |
} | |
// This isn't actually blocking. It creates two coroutines, one for polling for | |
// reads and one for writes. | |
func (m *Metrics) StartPoll() { | |
go m.pollGets() | |
go m.pollPuts() | |
} | |
// Notifies the getChan chanel about a read. This method doesn't block; it just | |
// fails if the channel's buffer is full (therefore in very rare cases there | |
// may be some loss of metrics). | |
func (m *Metrics) CaptureGet(key string) { | |
select { | |
case m.getChan <- key: | |
default: | |
// channel buffer full, metric dropped | |
} | |
} | |
// Notifies the putChan chanel about a write. This method doesn't block; it just | |
// fails if the channel's buffer is full (therefore in very rare cases there | |
// may be some loss of metrics). | |
func (m *Metrics) CapturePut(key string) { | |
select { | |
case m.putChan <- key: | |
default: | |
// channel buffer full, metric dropped | |
} | |
} | |
// Polls the getChan channel for messages and records them when they come. | |
// This runs in a goroutine, separately from pollPuts. | |
func (m *Metrics) pollGets() { | |
var key string | |
for { | |
key = <-m.getChan | |
// try to find the metric | |
count, found := m.getMetrics.Get(key) | |
if !found { | |
// if the metric wasn't found, create a new atomic uint32 | |
count = &atomic.Uint32{} | |
m.getMetrics.Put(key, count) | |
} | |
// get the underlying atomic uint32 behind the count interface{} | |
// and increase it | |
ac := count.(*atomic.Uint32) | |
ac.Add(1) | |
} | |
} | |
// Polls the putChan channel for messages and records them when they come. | |
// This runs in a goroutine, separately from pollGets. | |
func (m *Metrics) pollPuts() { | |
var key string | |
for { | |
key = <-m.putChan | |
// try to find the metric | |
count, found := m.putMetrics.Get(key) | |
if !found { | |
// if the metric wasn't found, create a new atomic uint32 | |
count = &atomic.Uint32{} | |
m.putMetrics.Put(key, count) | |
} | |
// get the underlying atomic uint32 behind the count interface{} | |
// and increase it | |
ac := count.(*atomic.Uint32) | |
ac.Add(1) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment