165 lines
4.1 KiB
Go
165 lines
4.1 KiB
Go
package handler
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/rabbitmq/amqp091-go"
|
|
"math/rand"
|
|
"samba/pkg/log"
|
|
"samba/pkg/repo"
|
|
"samba/pkg/rmq"
|
|
"samba/pkg/servername"
|
|
"samba/pkg/service"
|
|
"samba/util/config"
|
|
"samba/util/util"
|
|
)
|
|
|
|
type dbService struct {
|
|
service.IService
|
|
*repo.ClickHouseRepo
|
|
}
|
|
|
|
var gDBServices dbServices
|
|
|
|
type dbServices struct {
|
|
services []*dbService
|
|
}
|
|
|
|
func (d *dbServices) Get(uid int64) *dbService {
|
|
if uid < 0 {
|
|
i := rand.Int() % len(d.services)
|
|
return d.services[i]
|
|
}
|
|
return d.services[uid%int64(len(d.services))]
|
|
}
|
|
|
|
func (d *dbServices) QueueName(childId int) string {
|
|
return fmt.Sprintf("%v-%v", servername.ClickHouse, childId)
|
|
}
|
|
|
|
func (d *dbServices) Num() int {
|
|
return len(d.services)
|
|
}
|
|
|
|
func hallHandlerMessage(_ service.IService, d *amqp091.Delivery) {
|
|
var msg map[string]interface{}
|
|
if err := json.Unmarshal(d.Body, &msg); err != nil {
|
|
log.Error(fmt.Sprintf("consume message error: %v.body:%v", err, string(d.Body)))
|
|
return
|
|
}
|
|
//log.Debug(fmt.Sprintf("srv:%v recv msg:%v", s.Name(), string(d.Body)))
|
|
if fn, ok := MsgHandler[msg["a"].(string)]; ok {
|
|
fn(d, msg)
|
|
} else {
|
|
log.Error(fmt.Sprintf("msgId:%v not exist", msg["a"]))
|
|
}
|
|
}
|
|
|
|
func InitService() {
|
|
for j := 0; j < config.Cmd.ChildNum; j++ {
|
|
i := j
|
|
opts := []service.Option{
|
|
service.SetOnInit(func(s service.IService) bool {
|
|
if err := s.ExchangeDeclare(util.Direct(servername.ClickHouse), rmq.ExchangeDirect); err != nil {
|
|
log.Error(err.Error())
|
|
return false
|
|
}
|
|
if err := s.ExchangeDeclare(util.Topic(servername.ClickHouse), rmq.ExchangeTopic); err != nil {
|
|
log.Error(err.Error())
|
|
return false
|
|
}
|
|
if err := s.QueueDeclare(gDBServices.QueueName(i)); err != nil {
|
|
log.Error(err.Error())
|
|
return false
|
|
}
|
|
|
|
if !RegisterMsgHandler(s, i) {
|
|
return false
|
|
}
|
|
if err := s.Consume(gDBServices.QueueName(i)); err != nil {
|
|
log.Error(err.Error())
|
|
return false
|
|
}
|
|
log.Info(fmt.Sprintf("service:%v init", s.Name()))
|
|
return true
|
|
}),
|
|
service.SetOnNotifyStop(func(s service.IService) {
|
|
|
|
}),
|
|
service.SetCanStop(func(s service.IService) bool {
|
|
return true
|
|
}),
|
|
service.SetOnStop(func(s service.IService) {
|
|
if err := s.ConsumeDelete(); err != nil {
|
|
log.Error(err.Error())
|
|
} else {
|
|
log.Info(fmt.Sprintf("delete consume channle"))
|
|
}
|
|
if err := s.QueueDelete(gDBServices.QueueName(i)); err != nil {
|
|
log.Error(err.Error())
|
|
} else {
|
|
log.Info(fmt.Sprintf("delete queue:%v", gDBServices.QueueName(i)))
|
|
}
|
|
log.Info(fmt.Sprintf("service:%v stop", s.Name()))
|
|
}),
|
|
}
|
|
s := service.NewService(servername.ClickHouse, gDBServices.QueueName(i), config.RabbitmqUrl(), hallHandlerMessage, opts...)
|
|
dbs := &dbService{
|
|
IService: s,
|
|
}
|
|
cnf := &config.Config.ClickHouse
|
|
var err error
|
|
dbs.ClickHouseRepo, err = repo.InitClickHouse(cnf.Host, cnf.Port, cnf.Username, cnf.Password, cnf.DbName)
|
|
if err != nil {
|
|
log.Error(err.Error())
|
|
} else {
|
|
gDBServices.services = append(gDBServices.services, dbs)
|
|
}
|
|
}
|
|
}
|
|
|
|
func StopService() {
|
|
for _, s := range gDBServices.services {
|
|
s.NotifyStop()
|
|
}
|
|
for _, s := range gDBServices.services {
|
|
s.WaitStop()
|
|
}
|
|
}
|
|
|
|
func SendMsg(exchange, router, token string, uid int64, msgId string, msg interface{}) error {
|
|
data := service.Message{
|
|
MsgId: msgId,
|
|
Data: msg,
|
|
Token: token,
|
|
Uid: uid,
|
|
}
|
|
byteData, err := json.Marshal(data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
log.Debug(fmt.Sprintf("send msg:%v to exchange:%v, routKey:%v, data:%v", msgId, exchange, router, string(byteData)))
|
|
if err = gDBServices.Get(uid).Publish(exchange, router, byteData); err != nil {
|
|
log.Error(err.Error())
|
|
}
|
|
return err
|
|
}
|
|
|
|
func SendMsgToRPC(d *amqp091.Delivery, svr service.IService, data any, rid string, methodName ...string) {
|
|
rsp := map[string]any{
|
|
"a": util.Tie(len(rid) > 0, rid, "0"),
|
|
"p": data,
|
|
}
|
|
buf, err := json.Marshal(rsp)
|
|
if err == nil {
|
|
err = svr.PublishRpc(d, buf)
|
|
}
|
|
|
|
if err != nil {
|
|
log.Error(fmt.Sprintf("response RPC fail method=%s,err:%v", util.TieOrFn(len(methodName) <= 0, "unknown", func() string {
|
|
return methodName[0]
|
|
}), err))
|
|
}
|
|
|
|
}
|