ing
This commit is contained in:
parent
6d937770d3
commit
cf875b8b32
6
external/external.go
vendored
6
external/external.go
vendored
|
@ -1,11 +1,9 @@
|
|||
package external
|
||||
|
||||
import "git.loafle.net/overflow/gateway/external/grpc"
|
||||
|
||||
func InitPackage() {
|
||||
grpc.InitPackage()
|
||||
|
||||
}
|
||||
|
||||
func DestroyPackage() {
|
||||
grpc.DestroyPackage()
|
||||
|
||||
}
|
||||
|
|
2
external/grpc/grpc.go
vendored
2
external/grpc/grpc.go
vendored
|
@ -14,11 +14,13 @@ import (
|
|||
var grpcClient oci.OverflowApiServerClient
|
||||
|
||||
func InitPackage() {
|
||||
go func() {
|
||||
conn, err := grpc.Dial("192.168.1.50:50006", grpc.WithInsecure())
|
||||
if nil != err {
|
||||
logging.Logger().Panic(err)
|
||||
}
|
||||
grpcClient = oci.NewOverflowApiServerClient(conn)
|
||||
}()
|
||||
|
||||
}
|
||||
|
||||
|
|
46
external/kafka/kafka.go
vendored
Normal file
46
external/kafka/kafka.go
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
package kafka
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"git.loafle.net/commons/logging-go"
|
||||
"github.com/segmentio/kafka-go"
|
||||
)
|
||||
|
||||
var (
|
||||
kafkaWriter *kafka.Writer
|
||||
)
|
||||
|
||||
func InitPackage() {
|
||||
go func() {
|
||||
kafkaWriter = kafka.NewWriter(kafka.WriterConfig{
|
||||
Brokers: []string{"192.168.1.50:9092"},
|
||||
Topic: "overflow-metric-topic",
|
||||
Balancer: &kafka.LeastBytes{},
|
||||
})
|
||||
}()
|
||||
}
|
||||
|
||||
func DestroyPackage() {
|
||||
go func() {
|
||||
if err := kafkaWriter.Close(); nil != err {
|
||||
logging.Logger().Errorf("%v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func Write(key []byte, value []byte) error {
|
||||
if nil == kafkaWriter {
|
||||
return fmt.Errorf("Kafka client is not valid")
|
||||
}
|
||||
|
||||
err := kafkaWriter.WriteMessages(context.Background(),
|
||||
kafka.Message{
|
||||
Key: key,
|
||||
Value: value,
|
||||
},
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
26
external/redis/redis.go
vendored
Normal file
26
external/redis/redis.go
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
package redis
|
||||
|
||||
import (
|
||||
"github.com/gomodule/redigo/redis"
|
||||
)
|
||||
|
||||
var Pool *redis.Pool
|
||||
|
||||
func InitPackage() {
|
||||
go func() {
|
||||
Pool = &redis.Pool{
|
||||
MaxIdle: 1,
|
||||
MaxActive: 3,
|
||||
IdleTimeout: 240,
|
||||
Wait: true,
|
||||
MaxConnLifetime: 1,
|
||||
Dial: func() (redis.Conn, error) {
|
||||
return redis.Dial("tcp", "192.168.1.50:6379")
|
||||
},
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func DestroyPackage() {
|
||||
Pool.Close()
|
||||
}
|
|
@ -4,3 +4,6 @@ import:
|
|||
- package: git.loafle.net/commons/logging-go
|
||||
- package: google.golang.org/grpc
|
||||
version: ^1.11.2
|
||||
- package: github.com/gomodule/redigo
|
||||
version: ^2.0.0
|
||||
- package: github.com/segmentio/kafka-go
|
||||
|
|
69
subscribe/message.go
Normal file
69
subscribe/message.go
Normal file
|
@ -0,0 +1,69 @@
|
|||
package subscribe
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
TargetType TargetType `json:"targetType"`
|
||||
Targets []string `json:"targets"`
|
||||
MessageRaw *json.RawMessage `json:"message"`
|
||||
Message []byte
|
||||
}
|
||||
|
||||
type MessageBody struct {
|
||||
Version string `json:"jsonrpc"`
|
||||
Method string `json:"method"`
|
||||
Params interface{} `json:"params,omitempty"`
|
||||
}
|
||||
|
||||
type TargetType int
|
||||
|
||||
const (
|
||||
MEMBER_SESSION TargetType = iota
|
||||
MEMBER
|
||||
PROBE
|
||||
)
|
||||
|
||||
var (
|
||||
targetTypeID = map[TargetType]string{
|
||||
MEMBER_SESSION: "MEMBER_SESSION",
|
||||
MEMBER: "MEMBER",
|
||||
PROBE: "PROBE",
|
||||
}
|
||||
|
||||
targetTypeName = map[string]TargetType{
|
||||
"MEMBER_SESSION": MEMBER_SESSION,
|
||||
"MEMBER": MEMBER,
|
||||
"PROBE": PROBE,
|
||||
}
|
||||
)
|
||||
|
||||
func (st TargetType) String() string {
|
||||
return targetTypeID[st]
|
||||
}
|
||||
|
||||
func (st TargetType) MarshalJSON() ([]byte, error) {
|
||||
value, ok := targetTypeID[st]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("Invalid EnumType[%s] value", st)
|
||||
}
|
||||
return json.Marshal(value)
|
||||
}
|
||||
|
||||
func (st TargetType) UnmarshalJSON(b []byte) error {
|
||||
// unmarshal as string
|
||||
var s string
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
value, ok := targetTypeName[s]
|
||||
if !ok {
|
||||
return fmt.Errorf("Invalid EnumType[%s] value", s)
|
||||
}
|
||||
st = value
|
||||
return nil
|
||||
}
|
135
subscribe/redis/redis.go
Normal file
135
subscribe/redis/redis.go
Normal file
|
@ -0,0 +1,135 @@
|
|||
package redis
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
logging "git.loafle.net/commons/logging-go"
|
||||
"git.loafle.net/overflow/gateway/subscribe"
|
||||
"github.com/gomodule/redigo/redis"
|
||||
)
|
||||
|
||||
func New(conn redis.Conn) subscribe.Subscriber {
|
||||
return &Subscribers{
|
||||
Conn: conn,
|
||||
}
|
||||
}
|
||||
|
||||
type Subscribers struct {
|
||||
Conn redis.Conn
|
||||
pubSubConn *redis.PubSubConn
|
||||
subscriptions map[string]chan *subscribe.Message
|
||||
|
||||
stopChan chan struct{}
|
||||
stopWg sync.WaitGroup
|
||||
}
|
||||
|
||||
func (s *Subscribers) Start() error {
|
||||
if s.stopChan != nil {
|
||||
return fmt.Errorf("Subscriber: already running. Stop it before starting it again")
|
||||
}
|
||||
|
||||
if nil == s.Conn {
|
||||
return fmt.Errorf("Subscriber: Conn is nil")
|
||||
}
|
||||
|
||||
if nil == s.subscriptions {
|
||||
s.subscriptions = make(map[string]chan *subscribe.Message)
|
||||
}
|
||||
|
||||
s.pubSubConn = &redis.PubSubConn{Conn: s.Conn}
|
||||
|
||||
s.stopChan = make(chan struct{})
|
||||
|
||||
s.stopWg.Add(1)
|
||||
go s.handleSubscriber()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Subscribers) Stop() error {
|
||||
if s.stopChan == nil {
|
||||
return fmt.Errorf("Subscriber: must be started before stopping it")
|
||||
}
|
||||
close(s.stopChan)
|
||||
s.stopWg.Wait()
|
||||
s.stopChan = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Subscribers) Subscribe(channel string) (chan<- *subscribe.Message, error) {
|
||||
if _, ok := s.subscriptions[channel]; ok {
|
||||
return nil, subscribe.ChannelExistError{Channel: channel}
|
||||
}
|
||||
|
||||
if err := s.pubSubConn.Subscribe(channel); nil != err {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msgChan := make(chan *subscribe.Message)
|
||||
s.subscriptions[channel] = msgChan
|
||||
|
||||
return msgChan, nil
|
||||
}
|
||||
|
||||
func (s *Subscribers) Unsubscribe(channel string) error {
|
||||
msgChan, ok := s.subscriptions[channel]
|
||||
if !ok {
|
||||
return subscribe.ChannelIsNotExistError{Channel: channel}
|
||||
}
|
||||
delete(s.subscriptions, channel)
|
||||
close(msgChan)
|
||||
|
||||
return s.pubSubConn.Unsubscribe(channel)
|
||||
}
|
||||
|
||||
func (s *Subscribers) handleSubscriber() {
|
||||
var (
|
||||
receive interface{}
|
||||
)
|
||||
defer func() {
|
||||
if nil != s.subscriptions {
|
||||
for _, msgChan := range s.subscriptions {
|
||||
close(msgChan)
|
||||
}
|
||||
}
|
||||
|
||||
if nil != s.pubSubConn {
|
||||
s.pubSubConn.Close()
|
||||
}
|
||||
|
||||
s.stopWg.Done()
|
||||
}()
|
||||
|
||||
receiveChan := make(chan interface{})
|
||||
|
||||
for {
|
||||
go func() {
|
||||
receive = s.pubSubConn.Receive()
|
||||
receiveChan <- receive
|
||||
}()
|
||||
|
||||
select {
|
||||
case msg := <-receiveChan:
|
||||
switch v := msg.(type) {
|
||||
case redis.Message:
|
||||
msgChan, ok := s.subscriptions[v.Channel]
|
||||
if !ok {
|
||||
logging.Logger().Warnf("Subscriber: Channel[%s] is not exist", v.Channel)
|
||||
break
|
||||
}
|
||||
message := &subscribe.Message{}
|
||||
if err := json.Unmarshal(v.Data, message); nil != err {
|
||||
logging.Logger().Errorf("Subscriber: Cannot unmarshal data[%s] of Channel[%s] %v", string(v.Data), v.Channel, err)
|
||||
break
|
||||
}
|
||||
msgChan <- message
|
||||
case redis.Subscription:
|
||||
case error:
|
||||
}
|
||||
case <-s.stopChan:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
29
subscribe/subscriber.go
Normal file
29
subscribe/subscriber.go
Normal file
|
@ -0,0 +1,29 @@
|
|||
package subscribe
|
||||
|
||||
import "fmt"
|
||||
|
||||
type ChannelExistError struct {
|
||||
Channel string
|
||||
}
|
||||
|
||||
// Error returns the formatted configuration error.
|
||||
func (cee ChannelExistError) Error() string {
|
||||
return fmt.Sprintf("Subscriber: Channel[%q] is already subscribed.", cee.Channel)
|
||||
}
|
||||
|
||||
type ChannelIsNotExistError struct {
|
||||
Channel string
|
||||
}
|
||||
|
||||
// Error returns the formatted configuration error.
|
||||
func (cinee ChannelIsNotExistError) Error() string {
|
||||
return fmt.Sprintf("Subscriber: Channel[%q] is not subscribed.", cinee.Channel)
|
||||
}
|
||||
|
||||
type Subscriber interface {
|
||||
Start() error
|
||||
Stop() error
|
||||
|
||||
Subscribe(channel string) (chan<- *Message, error)
|
||||
Unsubscribe(channel string) error
|
||||
}
|
Loading…
Reference in New Issue
Block a user