Skip to content

Instantly share code, notes, and snippets.

@podikoglou
Created July 11, 2024 20:01
Show Gist options
  • Save podikoglou/4fb70f18cd29593e837c2c0f6e5c5f9c to your computer and use it in GitHub Desktop.
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
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