animated-sniffle/app/save.go

213 lines
4.3 KiB
Go
Raw Normal View History

2022-07-27 11:28:07 +03:00
package main
import (
"fmt"
"time"
)
type saveData struct {
Room string
From string
Rid int64
Amount int64
Now int64
}
type saveLog struct {
Rid int64
Now int64
Mes string
}
type DonatorCache struct {
Id int64
Last int64
}
func getDonId(name string) int64 {
2022-08-07 14:18:21 +03:00
var id int64
err := Mysql.Get(&id, "SELECT id FROM donator WHERE name=?", name)
2022-07-27 11:28:07 +03:00
if err != nil {
res, _ := Mysql.Exec("INSERT INTO donator (`name`) VALUES (?)", name)
2022-08-07 14:18:21 +03:00
id, _ = res.LastInsertId()
2022-07-27 11:28:07 +03:00
}
2022-08-07 14:18:21 +03:00
return id
2022-07-27 11:28:07 +03:00
}
2022-08-07 14:18:21 +03:00
func getRoomInfo(name string) (int64, bool) {
var id int64
2022-07-27 11:28:07 +03:00
result := true
2022-08-07 14:18:21 +03:00
err := Mysql.Get(&id, "SELECT id FROM room WHERE name=?", name)
2022-07-27 11:28:07 +03:00
if err != nil {
result = false
}
2022-08-07 14:18:21 +03:00
return id, result
}
func getSumTokens() int64 {
r := struct {
Date string
Sum int64
}{}
err := Clickhouse.Get(&r, "SELECT toStartOfHour(toDateTime(`unix`)) as date, SUM(`token`) as sum FROM `stat` WHERE time = today() GROUP BY date ORDER BY date DESC LIMIT 1")
if err == nil && r.Sum > 0 {
return r.Sum
}
return 0
2022-07-27 11:28:07 +03:00
}
func saveDB() {
2022-08-07 14:18:21 +03:00
hours, _, _ := time.Now().Clock()
2022-08-12 20:40:24 +03:00
bulk := []saveData{}
update := []struct {
Rid int64
Now int64
}{}
2022-07-27 11:28:07 +03:00
data := make(map[string]*DonatorCache)
2022-08-07 14:18:21 +03:00
index := make(map[string]int64)
2022-08-12 20:40:24 +03:00
ticker := time.NewTicker(10 * time.Second)
2023-05-14 13:53:05 +03:00
defer ticker.Stop()
cleanCache := time.NewTicker(12 * time.Hour)
defer cleanCache.Stop()
2022-08-12 20:40:24 +03:00
2022-08-07 14:18:21 +03:00
index = map[string]int64{"hours": int64(hours), "tokens": getSumTokens(), "last": time.Now().Unix()}
2022-07-27 11:28:07 +03:00
for {
select {
2023-05-14 13:53:05 +03:00
case <-cleanCache.C:
l := len(data)
now := time.Now().Unix()
for k, v := range data {
if now > v.Last+60*60*48 {
delete(data, k)
}
}
fmt.Println("Clean map:", l, "=>", len(data))
2022-08-12 20:40:24 +03:00
case <-ticker.C:
if len(bulk) > 0 {
2022-07-27 11:28:07 +03:00
tx, err := Mysql.Begin()
if err == nil {
2022-08-07 14:18:21 +03:00
st, _ := tx.Prepare("INSERT INTO `stat` (`did`, `rid`, `token`, `time`) VALUES (?, ?, ?, ?)")
2022-07-27 11:28:07 +03:00
for _, v := range bulk {
2022-08-07 14:18:21 +03:00
st.Exec(data[v.From].Id, v.Rid, v.Amount, v.Now)
}
tx.Commit()
st.Close()
}
tx, err = Mysql.Begin()
if err == nil {
st, _ := tx.Prepare("UPDATE `room` SET `last` = ? WHERE `id` = ?")
2022-08-12 20:40:24 +03:00
for _, v := range update {
st.Exec(v.Now, v.Rid)
2022-07-27 11:28:07 +03:00
}
2022-08-07 14:18:21 +03:00
tx.Commit()
st.Close()
2022-07-27 11:28:07 +03:00
}
tx, err = Clickhouse.Begin()
if err == nil {
2022-08-07 14:18:21 +03:00
st, _ := tx.Prepare("INSERT INTO stat VALUES (?, ?, ?, ?, ?)")
2022-07-27 11:28:07 +03:00
for _, v := range bulk {
2022-08-07 14:18:21 +03:00
st.Exec(uint32(data[v.From].Id), uint32(v.Rid), uint32(v.Amount), time.Unix(v.Now, 0), uint32(v.Now))
2022-07-27 11:28:07 +03:00
}
tx.Commit()
st.Close()
}
2022-08-12 20:40:24 +03:00
bulk = nil
update = nil
2022-07-27 11:28:07 +03:00
}
2022-08-12 20:40:24 +03:00
case m := <-save:
//fmt.Println("Save channel:", len(save), cap(save))
2022-08-07 14:18:21 +03:00
2022-08-12 20:40:24 +03:00
now := time.Now().Unix()
if _, ok := data[m.From]; ok {
data[m.From].Last = now
} else {
data[m.From] = &DonatorCache{Id: getDonId(m.From), Last: now}
}
bulk = append(bulk, m)
update = append(update, struct {
Rid int64
Now int64
}{
Rid: m.Rid,
Now: m.Now,
})
if m.Amount > 49 {
2022-08-07 14:18:21 +03:00
msg, err := json.Marshal(struct {
2023-05-11 14:40:18 +03:00
Chanel string `json:"chanel"`
2022-08-07 14:18:21 +03:00
Room string `json:"room"`
Donator string `json:"donator"`
Amount int64 `json:"amount"`
}{
2023-05-11 14:40:18 +03:00
Chanel: "bongacams",
2022-08-07 14:18:21 +03:00
Room: m.Room,
Donator: m.From,
Amount: m.Amount,
})
2022-07-27 11:28:07 +03:00
if err == nil {
2023-05-11 14:40:18 +03:00
socketServer <- msg
2022-07-27 11:28:07 +03:00
}
}
2022-08-07 14:18:21 +03:00
hours, minutes, seconds := time.Now().Clock()
if int64(hours) == index["hours"] {
index["tokens"] += m.Amount
} else {
index = map[string]int64{"hours": int64(hours), "tokens": 0, "last": 0}
}
if minutes >= 5 && now > index["last"]+30 {
seconds += minutes * 60
msg, err := json.Marshal(struct {
2023-05-14 13:53:05 +03:00
Chanel string `json:"chanel"`
Index float64 `json:"index"`
2023-05-11 14:40:18 +03:00
}{
2023-05-14 13:53:05 +03:00
Chanel: "bongacams",
Index: float64(index["tokens"]) / float64(seconds) * 3600 * 0.025 / 1000,
2023-05-11 14:40:18 +03:00
})
2022-08-07 14:18:21 +03:00
if err == nil {
2023-05-11 14:40:18 +03:00
socketServer <- msg
2022-08-07 14:18:21 +03:00
}
index["last"] = now
}
2022-07-27 11:28:07 +03:00
}
}
}
func saveLogs() {
2022-08-12 20:40:24 +03:00
bulk := []saveLog{}
ticker := time.NewTicker(10 * time.Second)
2023-05-14 13:53:05 +03:00
defer ticker.Stop()
2022-07-27 11:28:07 +03:00
for {
select {
2022-08-12 20:40:24 +03:00
case <-ticker.C:
if len(bulk) > 0 {
tx, err := Mysql.Begin()
if err == nil {
st, _ := tx.Prepare("INSERT INTO `logs` (`rid`, `time`, `mes`) VALUES (?, ?, ?)")
for _, v := range bulk {
st.Exec(v.Rid, v.Now, v.Mes)
2022-07-27 11:28:07 +03:00
}
2022-08-12 20:40:24 +03:00
tx.Commit()
st.Close()
2022-07-27 11:28:07 +03:00
}
2022-08-12 20:40:24 +03:00
bulk = nil
}
case m := <-slog:
if len(m.Mes) > 0 {
bulk = append(bulk, m)
2022-07-27 11:28:07 +03:00
}
}
}
}