Skip to content

Instantly share code, notes, and snippets.

@soyart
Last active June 27, 2022 05:46
Show Gist options
  • Select an option

  • Save soyart/2651a2b71b0b87fcd9c2da5aa555ea03 to your computer and use it in GitHub Desktop.

Select an option

Save soyart/2651a2b71b0b87fcd9c2da5aa555ea03 to your computer and use it in GitHub Desktop.
Practice code for alerting with varying intervals for different severity levels
package main
import (
"crypto/rand"
"fmt"
"math/big"
"strings"
"time"
)
type level int
const (
NULL level = iota
SAFE // ALERT ONCE
WARN
CRITICAL
CATASTROPHE
)
var (
updateInterval = time.Duration(time.Second * 1)
// Alert interval in seconds
intervals = map[level]time.Duration{
SAFE: time.Second * time.Duration(20),
WARN: time.Second * time.Duration(10),
CRITICAL: time.Second * time.Duration(5),
CATASTROPHE: time.Second * time.Duration(2),
}
treshold = big.NewInt(25)
tresholdx2 = new(big.Int).Mul(treshold, big.NewInt(2))
tresholdx4 = new(big.Int).Mul(treshold, big.NewInt(4))
)
type alert struct {
level level
balance *big.Int
}
func main() {
c := make(chan alert)
go notifyAlert(c) // notifyAlert randomizes alerts
// go notifyAlertMock(c) // notifyAlert mocks alerts
// go notifySafe(c) // notifySafe only pushes SAFE alert into c
alertFunc(c)
}
// event generator
func notifyAlert(c chan<- alert) {
for {
balance, err := rand.Int(rand.Reader, big.NewInt(300))
if err != nil {
panic(err.Error())
}
var mostRecent alert
if cmp := balance.Cmp(tresholdx4); cmp == 1 {
mostRecent.level = SAFE
} else if cmp := balance.Cmp(tresholdx2); cmp == 1 {
mostRecent.level = WARN
} else if cmp := balance.Cmp(treshold); cmp == 1 {
mostRecent.level = CRITICAL
} else {
mostRecent.level = CATASTROPHE
}
c <- mostRecent
time.Sleep(updateInterval)
}
}
// event consumer
func alertFunc(c <-chan alert) {
var prevLevel level = NULL
var prevTime time.Time
for a := range c {
interval := intervals[a.level]
thisTime := time.Now()
if a.level != prevLevel {
printAlert(a)
// Alert right away if level changes
prevTime = thisTime
} else {
// If level stays the same, only alert if time has elasped past the interval
if elapsed := time.Since(prevTime); elapsed >= interval && a.level != SAFE {
printAlert(a)
prevTime = thisTime
}
printBail(a)
}
prevLevel = a.level
}
}
func notifySafe(c chan<- alert) {
for i := 0; i < 30; i++ {
c <- alert{level: SAFE}
time.Sleep(updateInterval)
}
close(c)
}
func notifyAlertMock(c chan<- alert) {
l1 := alert{level: SAFE}
l2 := alert{level: WARN}
l3 := alert{level: CRITICAL}
l4 := alert{level: CATASTROPHE}
mock := []alert{l1, l1, l1, l1, l1, l1, l2, l2, l3, l2, l3, l4, l4, l4}
for _, a := range mock {
c <- a
time.Sleep(updateInterval)
}
close(c)
}
func pront(s string, alert alert) {
fmt.Printf("%s!\t%d %v\t%s\n", s, alert.level, alert.balance, strings.Split(time.Now().String(), " ")[1])
}
func printAlert(alert alert) {
pront("ALERT", alert)
}
func printBail(alert alert) {
pront("BAIL", alert)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment