feat: observe changes in repository to automatically clear cache
All checks were successful
Cadoles/bouncer/pipeline/pr-master This commit looks good
All checks were successful
Cadoles/bouncer/pipeline/pr-master This commit looks good
This commit is contained in:
85
internal/store/redis/proxy_observable.go
Normal file
85
internal/store/redis/proxy_observable.go
Normal file
@ -0,0 +1,85 @@
|
||||
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{}
|
Reference in New Issue
Block a user