Skip to content

Commit

Permalink
added auto updated functionality for locally cached rules
Browse files Browse the repository at this point in the history
  • Loading branch information
x-sushant-x committed Nov 4, 2024
1 parent 1ce3f4c commit b441985
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 14 deletions.
24 changes: 12 additions & 12 deletions rate_shield/limiter/limiter.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,22 +85,22 @@ func (l *Limiter) GetRule(key string) (*models.Rule, bool, error) {

func (l *Limiter) StartRateLimiter() {
log.Info().Msg("Starting Limiter Service ✅")
l.cachedRules = l.cacheRulesLoally()
l.cachedRules = l.redisRuleSvc.CacheRulesLocally()
l.tokenBucket.startAddTokenJob()
go l.listenToRulesUpdate()

}

func (l *Limiter) cacheRulesLoally() map[string]*models.Rule {
rules, err := l.redisRuleSvc.GetAllRules()
if err != nil {
log.Err(err).Msg("Unable to cache all rules locally")
}
func (l *Limiter) listenToRulesUpdate() {
updatesChannel := make(chan string)
go l.redisRuleSvc.ListenToRulesUpdate(updatesChannel)

cachedRules := make(map[string]*models.Rule)
for {
data := <-updatesChannel

for _, rule := range rules {
cachedRules[rule.APIEndpoint] = &rule
if data == "UpdateRules" {
l.cachedRules = l.redisRuleSvc.CacheRulesLocally()
log.Info().Msg("Rules Updated Successfully")
}
}

log.Info().Msg("Rules locally cached ✅")
return cachedRules
}
2 changes: 2 additions & 0 deletions rate_shield/redis/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ type RedisRuleClient interface {
GetAllRuleKeys() ([]string, bool, error)
SetRule(key string, val interface{}) error
DeleteRule(key string) error
PublishMessage(channel, msg string) error
ListenToRulesUpdate(udpatesChannel chan string)
}

type RedisFixedWindowClient interface {
Expand Down
26 changes: 26 additions & 0 deletions rate_shield/redis/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ import (
"encoding/json"

"github.com/redis/go-redis/v9"
"github.com/rs/zerolog/log"
"github.com/x-sushant-x/RateShield/models"
)

const (
redisRuleUpdateChannel = "rules-update"
)

type RedisRules struct {
client *redis.Client
}
Expand Down Expand Up @@ -52,3 +57,24 @@ func (r RedisRules) SetRule(key string, val interface{}) error {
}
return nil
}

func (r RedisRules) PublishMessage(channel, msg string) error {
return r.client.Publish(ctx, channel, msg).Err()
}

func (r RedisRules) ListenToRulesUpdate(updatesChannel chan string) {
pubsub := r.client.Subscribe(ctx, redisRuleUpdateChannel)
defer pubsub.Close()

for {
msg, err := pubsub.ReceiveMessage(ctx)
if err != nil {
log.Err(err).Msg("Error while listening for rule updates")
continue
}

if msg.Channel == redisRuleUpdateChannel {
updatesChannel <- "UpdateRules"
}
}
}
31 changes: 29 additions & 2 deletions rate_shield/service/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@ import (
redisClient "github.com/x-sushant-x/RateShield/redis"
)

const (
redisChannel = "rules-update"
)

type RulesService interface {
GetAllRules() ([]models.Rule, error)
GetRule(key string) (*models.Rule, bool, error)
SearchRule(searchText string) ([]models.Rule, error)
CreateOrUpdateRule(models.Rule) error
DeleteRule(endpoint string) error
CacheRulesLocally() map[string]*models.Rule
ListenToRulesUpdate(updatesChannel chan string)
}

type RulesServiceRedis struct {
Expand Down Expand Up @@ -79,7 +85,8 @@ func (s RulesServiceRedis) CreateOrUpdateRule(rule models.Rule) error {
log.Err(err).Msg("unable to create or update rule")
return err
}
return nil

return s.redisClient.PublishMessage(redisChannel, "rule-updated")
}

func (s RulesServiceRedis) DeleteRule(endpoint string) error {
Expand All @@ -89,5 +96,25 @@ func (s RulesServiceRedis) DeleteRule(endpoint string) error {
return err

}
return err
return s.redisClient.PublishMessage(redisChannel, "rule-updated")
}

func (s RulesServiceRedis) CacheRulesLocally() map[string]*models.Rule {
rules, err := s.GetAllRules()
if err != nil {
log.Err(err).Msg("Unable to cache all rules locally")
}

cachedRules := make(map[string]*models.Rule)

for _, rule := range rules {
cachedRules[rule.APIEndpoint] = &rule
}

log.Info().Msg("Rules locally cached ✅")
return cachedRules
}

func (s RulesServiceRedis) ListenToRulesUpdate(updatesChannel chan string) {
s.redisClient.ListenToRulesUpdate(updatesChannel)
}

0 comments on commit b441985

Please sign in to comment.