Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
faeeeea9f5 | ||
|
|
a976425a4f | ||
|
|
eb865afb96 |
22
Makefile
Normal file
22
Makefile
Normal file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env gmake -f
|
||||
|
||||
GOOPTS=CGO_ENABLED=0
|
||||
BUILDOPTS=-ldflags="-s -w" -a -gcflags=all=-l
|
||||
|
||||
all: clean build
|
||||
|
||||
build:
|
||||
${GOOPTS} go build ${BUILDOPTS}
|
||||
|
||||
clean:
|
||||
go clean
|
||||
|
||||
wipe:
|
||||
go clean
|
||||
rm -rf go.{mod,sum}
|
||||
|
||||
prep:
|
||||
go mod init main
|
||||
go mod tidy -compat=1.17
|
||||
|
||||
# vim: set ft=make noet ai ts=4 sw=4 sts=4:
|
||||
81
main.go
81
main.go
@@ -6,8 +6,10 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/go-redis/redis/v8"
|
||||
@@ -35,8 +37,8 @@ type myConfig struct {
|
||||
// Входящее сообщение из pubsub-канала redis-ки
|
||||
type rMsg struct {
|
||||
From string `json:"from,omitempty"`
|
||||
Chatid int64 `json:"chatid,omitempty"`
|
||||
Userid int64 `json:"userid,omitempty"`
|
||||
Chatid string `json:"chatid,omitempty"`
|
||||
Userid string `json:"userid,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Plugin string `json:"plugin,omitempty"`
|
||||
Mode string `json:"mode,omitempty"`
|
||||
@@ -54,8 +56,8 @@ type rMsg struct {
|
||||
// Исходящее сообщение в pubsub-канал redis-ки
|
||||
type sMsg struct {
|
||||
From string `json:"from"`
|
||||
Chatid int64 `json:"chatid"`
|
||||
Userid int64 `json:"userid"`
|
||||
Chatid string `json:"chatid"`
|
||||
Userid string `json:"userid"`
|
||||
Message string `json:"message"`
|
||||
Plugin string `json:"plugin"`
|
||||
Mode string `json:"mode"`
|
||||
@@ -76,8 +78,18 @@ var config myConfig
|
||||
// To break circular message forwarding we must set some sane default, it can be overridden via config
|
||||
var forwardMax int64 = 5
|
||||
|
||||
// Дефолтный конфиг клиента-редиски
|
||||
// Объектики клиента-редиски
|
||||
var redisClient *redis.Client
|
||||
var subscriber *redis.PubSub
|
||||
|
||||
// Main context
|
||||
var ctx = context.Background()
|
||||
|
||||
// Ставится в true, если мы получили сигнал на выключение
|
||||
var shutdown = false
|
||||
|
||||
// Канал, в который приходят уведомления для хэндлера сигналов от траппера сигналов
|
||||
var sigChan = make(chan os.Signal, 1)
|
||||
|
||||
// Горутинка, которая парсит json-чики прилетевшие из REDIS-ки
|
||||
func msgParser(ctx context.Context, msg string) {
|
||||
@@ -97,12 +109,12 @@ func msgParser(ctx context.Context, msg string) {
|
||||
return
|
||||
}
|
||||
|
||||
if exist := j.Chatid; exist == 0 {
|
||||
if exist := j.Chatid; exist == "" {
|
||||
log.Warnf("Incorrect msg from redis, no chatid field: %s", msg)
|
||||
return
|
||||
}
|
||||
|
||||
if exist := j.Userid; exist == 0 {
|
||||
if exist := j.Userid; exist == "" {
|
||||
log.Warnf("Incorrect msg from redis, no userid field: %s", msg)
|
||||
return
|
||||
}
|
||||
@@ -389,6 +401,41 @@ func readConfig() {
|
||||
}
|
||||
}
|
||||
|
||||
// Хэндлер сигналов закрывает все бд и сваливает из приложения
|
||||
func sigHandler() {
|
||||
var err error
|
||||
|
||||
for {
|
||||
var s = <-sigChan
|
||||
switch s {
|
||||
case syscall.SIGINT:
|
||||
log.Infoln("Got SIGINT, quitting")
|
||||
case syscall.SIGTERM:
|
||||
log.Infoln("Got SIGTERM, quitting")
|
||||
case syscall.SIGQUIT:
|
||||
log.Infoln("Got SIGQUIT, quitting")
|
||||
|
||||
// Заходим на новую итерацию, если у нас "неинтересный" сигнал
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
// Чтобы не срать в логи ошибками от редиски, проставим shutdown state приложения в true
|
||||
shutdown = true
|
||||
|
||||
// Отпишемся от всех каналов и закроем коннект к редиске
|
||||
if err = subscriber.Unsubscribe(ctx); err != nil {
|
||||
log.Errorf("Unable to unsubscribe from redis channels cleanly: %s", err)
|
||||
}
|
||||
|
||||
if err = subscriber.Close(); err != nil {
|
||||
log.Errorf("Unable to close redis connection cleanly: %s", err)
|
||||
}
|
||||
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
// Производит некоторую инициализацию перед запуском main()
|
||||
func init() {
|
||||
log.SetFormatter(&log.TextFormatter{
|
||||
@@ -440,14 +487,30 @@ func main() {
|
||||
})
|
||||
|
||||
log.Debugf("Lazy connect() to redis at %s:%d", config.Server, config.Port)
|
||||
subscriber := redisClient.Subscribe(ctx, config.Channel)
|
||||
subscriber = redisClient.Subscribe(ctx, config.Channel)
|
||||
|
||||
// Самое время поставить траппер сигналов
|
||||
signal.Notify(sigChan,
|
||||
syscall.SIGINT,
|
||||
syscall.SIGTERM,
|
||||
syscall.SIGQUIT)
|
||||
|
||||
go sigHandler()
|
||||
|
||||
// Обработчик событий от редиски
|
||||
for {
|
||||
if shutdown {
|
||||
time.Sleep(1 * time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
msg, err := subscriber.ReceiveMessage(ctx)
|
||||
|
||||
if err != nil {
|
||||
log.Warnf("Unable to connect to redis at %s:%d: %s", config.Server, config.Port, err)
|
||||
if !shutdown {
|
||||
log.Warnf("Unable to connect to redis at %s:%d: %s", config.Server, config.Port, err)
|
||||
}
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user