package redis import ( "bytes" "context" "encoding/gob" "forge.cadoles.com/cadoles/bouncer/internal/store" "github.com/pkg/errors" "gitlab.com/wpetit/goweb/logger" ) func init() { gob.Register(&ProxyChange{}) } type ProxyChange struct { Operation ChangeOperation Proxy store.ProxyName } // Change implements store.Change. func (p *ProxyChange) Change() {} func NewProxyChange(op ChangeOperation, name store.ProxyName) *ProxyChange { return &ProxyChange{ Operation: op, Proxy: name, } } var _ store.Change = &ProxyChange{} const proxyChangeChannel string = "proxy-changes" // Changes implements store.Observable. func (r *ProxyRepository) Changes(ctx context.Context, fn func(store.Change)) { go func() { sub := r.client.Subscribe(ctx, proxyChangeChannel) defer sub.Close() for { var buff bytes.Buffer decoder := gob.NewDecoder(&buff) msg, err := sub.ReceiveMessage(ctx) if err != nil { logger.Error(ctx, "could not receive message", logger.E(errors.WithStack(err))) return } buff.Reset() buff.WriteString(msg.Payload) change := &ProxyChange{} if err := decoder.Decode(change); err != nil { logger.Error(ctx, "could not decode message", logger.E(errors.WithStack(err))) continue } fn(change) } }() } func (r *ProxyRepository) notifyChange(op ChangeOperation, name store.ProxyName) { change := NewProxyChange(op, name) var buff bytes.Buffer encoder := gob.NewEncoder(&buff) ctx := context.Background() if err := encoder.Encode(change); err != nil { logger.Error(ctx, "could not encode message", logger.E(errors.WithStack(err))) return } if err := r.client.Publish(ctx, proxyChangeChannel, buff.Bytes()).Err(); err != nil { logger.Error(ctx, "could not publish message", logger.E(errors.WithStack(err))) return } } var _ store.Observable = &ProxyRepository{}