fayec/subscription/subscription.go

81 lines
2.0 KiB
Go

package subscription
import (
"errors"
"gitea.watsonlabs.net/watsonb8/fayec/message"
"regexp"
)
var ErrInvalidChannelName = errors.New("invalid channel channel")
type Unsubscriber func(subscription *Subscription) error
type Subscription struct {
channel string
authToken string
unsub Unsubscriber
msgCh chan *message.Message
}
// todo error
func NewSubscription(chanel string, unsub Unsubscriber, authToken string, msgCh chan *message.Message) (*Subscription, error) {
if !IsValidSubscriptionName(chanel) {
return nil, ErrInvalidChannelName
}
return &Subscription{
channel: chanel,
authToken: authToken,
unsub: unsub,
msgCh: msgCh,
}, nil
}
func (s *Subscription) OnMessage(onMessage func(channel string, msg message.Data)) error {
var inMsg *message.Message
go s.StartMessageLoop(inMsg, onMessage)
return nil
}
func (s *Subscription) StartMessageLoop(inMsg *message.Message, callback func(channel string, msg message.Data)) error {
for inMsg = range s.msgCh {
if inMsg.GetError() != nil {
return inMsg.GetError()
}
callback(inMsg.Channel, inMsg.Data)
}
return nil
}
func (s *Subscription) MsgChannel() chan *message.Message {
return s.msgCh
}
func (s *Subscription) Name() string {
return s.channel
}
// Unsubscribe ...
func (s *Subscription) Unsubscribe() error {
return s.unsub(s)
}
func (s *Subscription) AuthToken() string {
return s.authToken
}
// validChannelName channel specifies is the channel is in the format /foo/432/bar
var validChannelName = regexp.MustCompile(`^\/(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+(\/(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+)*$`)
var validChannelPattern = regexp.MustCompile(`^(\/(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+)*\/\*{1,2}$`)
func IsValidSubscriptionName(channel string) bool {
return validChannelName.MatchString(channel) || validChannelPattern.MatchString(channel)
}
// isValidPublishName
func IsValidPublishName(channel string) bool {
return validChannelName.MatchString(channel)
}