2022-07-27 11:34:26 +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 {
var id int64
err := Mysql . Get ( & id , "SELECT id FROM donator WHERE name=?" , name )
if err != nil {
res , _ := Mysql . Exec ( "INSERT INTO donator (`name`) VALUES (?)" , name )
id , _ = res . LastInsertId ( )
}
return id
}
func getRoomInfo ( name string ) ( int64 , bool ) {
var id int64
result := true
err := Mysql . Get ( & id , "SELECT id FROM room WHERE name=?" , name )
if err != nil {
result = false
}
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
}
func saveDB ( ) {
2022-08-12 20:22:29 +03:00
bulk := [ ] saveData { }
update := [ ] struct {
Rid int64
Now int64
} { }
2023-05-14 23:28:56 +03:00
tokens := getSumTokens ( )
hour := time . Now ( ) . Hour ( )
2022-07-27 11:34:26 +03:00
data := make ( map [ string ] * DonatorCache )
2022-08-12 20:22:29 +03:00
ticker := time . NewTicker ( 10 * time . Second )
2023-05-13 17:38:12 +03:00
defer ticker . Stop ( )
2023-05-14 13:57:18 +03:00
2023-05-14 23:28:56 +03:00
sendIndex := time . NewTicker ( 30 * time . Second )
defer sendIndex . Stop ( )
2023-05-13 17:38:12 +03:00
cleanCache := time . NewTicker ( 12 * time . Hour )
defer cleanCache . Stop ( )
2022-08-12 20:22:29 +03:00
2022-07-27 11:34:26 +03:00
for {
select {
2023-05-14 23:28:56 +03:00
case <- sendIndex . C :
2023-05-15 13:25:43 +03:00
t := time . Now ( )
if t . Minute ( ) >= 5 && tokens > 0 {
passed := t . Second ( ) + t . Minute ( ) * 60
2023-05-14 23:28:56 +03:00
msg , err := json . Marshal ( struct {
Chanel string ` json:"chanel" `
Index int64 ` json:"index" `
} {
Chanel : "chaturbate" ,
Index : tokens / int64 ( passed ) * 3600 / 1000 * 5 / 100 ,
} )
if err == nil {
socketServer <- msg
}
}
2023-05-13 17:38:12 +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:22:29 +03:00
case <- ticker . C :
if len ( bulk ) > 0 {
2022-07-27 11:34:26 +03:00
tx , err := Mysql . Begin ( )
if err == nil {
st , _ := tx . Prepare ( "INSERT INTO `stat` (`did`, `rid`, `token`, `time`) VALUES (?, ?, ?, ?)" )
for _ , v := range bulk {
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:22:29 +03:00
for _ , v := range update {
st . Exec ( v . Now , v . Rid )
2022-07-27 11:34:26 +03:00
}
tx . Commit ( )
st . Close ( )
}
tx , err = Clickhouse . Begin ( )
if err == nil {
st , _ := tx . Prepare ( "INSERT INTO stat VALUES (?, ?, ?, ?, ?)" )
for _ , v := range bulk {
st . Exec ( uint32 ( data [ v . From ] . Id ) , uint32 ( v . Rid ) , uint32 ( v . Amount ) , time . Unix ( v . Now , 0 ) , uint32 ( v . Now ) )
}
tx . Commit ( )
st . Close ( )
}
2022-08-12 20:22:29 +03:00
bulk = nil
update = nil
2022-07-27 11:34:26 +03:00
}
2022-08-12 20:22:29 +03:00
case m := <- save :
//fmt.Println("Save channel:", len(save), cap(save))
2023-05-14 23:28:56 +03:00
t := time . Now ( )
2022-08-12 20:22:29 +03:00
if _ , ok := data [ m . From ] ; ok {
2023-05-14 23:28:56 +03:00
data [ m . From ] . Last = t . Unix ( )
2022-08-12 20:22:29 +03:00
} else {
2023-05-14 23:28:56 +03:00
data [ m . From ] = & DonatorCache { Id : getDonId ( m . From ) , Last : t . Unix ( ) }
2022-08-12 20:22:29 +03:00
}
2023-05-14 23:28:56 +03:00
if hour != t . Hour ( ) {
tokens = 0
hour = t . Hour ( )
}
tokens += m . Amount
2022-08-12 20:22:29 +03:00
bulk = append ( bulk , m )
update = append ( update , struct {
Rid int64
Now int64
} {
Rid : m . Rid ,
Now : m . Now ,
} )
2022-07-27 11:34:26 +03:00
if m . Amount > 99 {
msg , err := json . Marshal ( struct {
2023-05-11 13:52:11 +03:00
Chanel string ` json:"chanel" `
2022-07-27 11:34:26 +03:00
Room string ` json:"room" `
Donator string ` json:"donator" `
Amount int64 ` json:"amount" `
} {
2023-05-11 13:52:11 +03:00
Chanel : "chaturbate" ,
2022-07-27 11:34:26 +03:00
Room : m . Room ,
Donator : m . From ,
Amount : m . Amount ,
} )
if err == nil {
2023-05-11 13:52:11 +03:00
socketServer <- msg
2022-07-27 11:34:26 +03:00
}
}
}
}
}
func saveLogs ( ) {
2022-08-12 20:22:29 +03:00
bulk := [ ] saveLog { }
ticker := time . NewTicker ( 10 * time . Second )
2023-05-13 17:38:12 +03:00
defer ticker . Stop ( )
2022-07-27 11:34:26 +03:00
for {
select {
2022-08-12 20:22:29 +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:34:26 +03:00
}
2022-08-12 20:22:29 +03:00
tx . Commit ( )
st . Close ( )
2022-07-27 11:34:26 +03:00
}
2022-08-12 20:22:29 +03:00
bulk = nil
}
case m := <- slog :
2023-07-03 22:50:23 +03:00
//fmt.Println("slog", len(slog), cap(slog))
2022-08-12 20:22:29 +03:00
if len ( m . Mes ) > 0 {
bulk = append ( bulk , m )
2022-07-27 11:34:26 +03:00
}
}
}
}